Spring Security - JDBC Authentication

Configure JDBC based Authentication

Database Setup

You need to setup the database first before using JDBC Authenticaion.

Spring security provides a default schema for JDBC based authentication. You can find the default schema from https://docs.spring.io/spring-security/site/docs/current/reference/html5/

schema.sql

1
2
3
4
5
6
7
8
9
10
11
12
create table users(
username varchar_ignorecase(255) not null primary key,
password varchar_ignorecase(255) 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);

data.sql - add sample data. Insert two users with password equals ‘password’.

1
2
3
4
5
6
INSERT INTO users(username, password, enabled) values('user', '$2a$10$q.YKOfjjfHhGxYaGp/hSFe0VTPCMPJo9cu/TmVZEwulMMqHZhLGZ2', true);
INSERT INTO users(username, password, enabled) values('admin', '$2a$10$q.YKOfjjfHhGxYaGp/hSFe0VTPCMPJo9cu/TmVZEwulMMqHZhLGZ2', true);

INSERT INTO authorities(username, authority) values('user', 'ROLE_USER');
INSERT INTO authorities(username, authority) values('admin', 'ROLE_USER');
INSERT INTO authorities(username, authority) values('admin', 'ROLE_ADMIN');

JDBC Authentication

For JDBC Authentication We need to setup the datasource to use in the configuration class.

SecurityConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;

@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().formLogin();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource);
}
}

AuthenticationManagerBuilder.jdbcAuthentication() method configures Spring Security to use JDBC authentication. and returns JdbcUserDetailsManagerConfigurer to allow customization of the JDBC authentication.

The only required method is the dataSource(javax.sql.DataSource) all other methods have reasonable defaults.

Here we use BCryptPasswordEncoder. The default is to use plain text, which you shouldn’t use in real world.

Reference