Spring Boot Security- Authorization and Authentication in JDBC and H2.
In Spring Boot, you can implement authorization and authentication using Spring Security with a JDBC authentication provider and an H2 database. Here's a step-by-step guide on how to set it up:
Step 1: Add Spring Security , H2 and various other important dependencies Add the following dependencies to your pom.xml
For Maven:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>spring-security-jdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-security-jdbc</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Step 2: Configure Spring Security Create a configuration class that extends WebSecurityConfigurerAdapter and overrides the necessary methods. For example:
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Deprecated
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.jdbcAuthentication()
.dataSource(dataSource);
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN","USER")
.antMatchers("/").permitAll()
.and().formLogin();
}
@Bean
public PasswordEncoder getPasswordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
}
In the configure(AuthenticationManagerBuilder auth) method, we configure the JDBC authentication provider and specify the queries to retrieve user details and authorities from the database.
In the configure(HttpSecurity http) method, we configure the URL patterns and access rules. In this example, / is accessible to all, and any other request requires authentication.
Step 3: Create database tables Create the necessary database tables for users and authorities. You can use the following SQL statements as an example:
schema.sql in the resources folder
create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(500) not null,
enabled boolean not null
);
create table authorities (
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);
Step 4: Now insert values and roles in the schema or table. Create data.sql in the same resources folder.
INSERT INTO users( username, password, enabled)
values('user','pass',true);
INSERT INTO users( username, password, enabled)
values('admin','pass',true);
INSERT INTO authorities(username, authority)
values('user', 'ROLE_USER');
INSERT INTO authorities(username, authority)
values('admin', 'ROLE_ADMIN');
Step 6: Now create the basic and important task, the controller, where you can create various API's to test your application.
HomeResources.java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeResource{
@GetMapping("/")
public String home() {
return("<h1>Welcome</h1>");
}
@GetMapping("/user")
public String user() {
return("<h1>Welcome User</h1>");
}
@GetMapping("/admin")
public String admin() {
return("<h1>Welcome Admin</h1>");
}
}
Now here you go, run the main application and then go to localhost:8080/user (or any other default URL or port address of your Tomcat server) and you could see its asking for credentials. Similarly you can test localhost:8080/admin and localhost:8080/.