

Table of Contents
1. Overview
In the previous example, we have discussed about spring boot OAuth 2 authentication server configuration but it was storing token in-memory. Here is an explanation of Spring boot Oauth2 JDBC token store example:
Advantages of store token information in the database:
- If multiple authentication servers used for load balancing at that time token store must be share which can be archive JDBC token store.
- If authentication server needs to restart in this case in-memory token will be loss that problem can be solve using JDBC token store.
2. Example

Spring boot OAuth2 JDBC token store example
2.1 pom.xml
spring-boot-starter-jdbc requires to database configuration, mysql-connector-java drive for MySQL database connection
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-boot-example</groupId>
<artifactId>Spring-boot-Oauth2-JDBC-token-store-example</artifactId>
<version>1.0-SNAPSHOT</version>
<description>Spring boot Oauth2 JDBC token store example</description>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId> <!--starter require for spring boot spring security-->
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId> <!--It contains database base related classes-->
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>2.2 schema.sql
schema.sql file must be available insider resources folder so automatically schema will be created in the database. Or Also possible to execute the script manually.
create table if not exists oauth_access_token ( token_id VARCHAR(255), token LONG VARBINARY, authentication_id VARCHAR(255) PRIMARY KEY, user_name VARCHAR(255), client_id VARCHAR(255), authentication LONG VARBINARY, refresh_token VARCHAR(255) ); create table if not exists oauth_refresh_token ( token_id VARCHAR(255), token LONG VARBINARY, authentication LONG VARBINARY );
2.3 application.properties
application.properties contains database properties where tokens information will be store
spring.datasource.url=jdbc:mysql://localhost/demo_database spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.jdbc.Driver debug=true
2.4 SecurityOAuth2Configuration
JdbcTokenStore requires database source which will be used to store token related information. TokenStore bean will be passed to AuthorizationServerEndpointsConfigurer endpoints.
@EnableAuthorizationServer indicate that consider current server or service as authentication server or service
package com.javadeveloperzone;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import javax.sql.DataSource;
/**
* Created by JavaDeveloperZone on 04-08-2017.
*/
@Configuration
@EnableAuthorizationServer
public class SecurityOAuth2Configuration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("javadeveloperzone")
.secret("secret")
.accessTokenValiditySeconds(2000) // expire time for access token
.refreshTokenValiditySeconds(-1) // expire time for refresh token
.scopes("read", "write") // scope related to resource server
.authorizedGrantTypes("password", "refresh_token"); // grant type
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints.tokenStore(tokenStore());
}
}
2.5 SecurityConfiguration
Spring Security-related configuration like user, role, and credential has been in-memory for the simple example.
package com.javadeveloperzone;
import org.springframework.beans.factory.annotation.Autowired;
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.WebSecurityConfigurerAdapter;
/**
* Created by JavaDeveloperZone on 09-12-2017.
*/
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.authenticated();
}
@Autowired // here is configuration related to spring boot basic authentication
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication() // static users
.withUser("zone1").password("mypassword").roles("USER")
.and()
.withUser("zone2").password("mypassword").roles("USER")
.and()
.withUser("zone3").password("mypassword").roles("USER")
.and()
.withUser("zone4").password("mypassword").roles("USER")
.and()
.withUser("zone5").password("mypassword").roles("USER");
}
}
2.6 SpringBootApplication
package com.javadeveloperzone;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* Created by JavaDeveloperZone on 19-07-2017.
*/
@org.springframework.boot.autoconfigure.SpringBootApplication
@ComponentScan({"com.javadeveloperzone"})
// Using a root package also allows the @ComponentScan annotation to be used without needing to specify a basePackage attribute
public class SpringBootApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootApplication.class, args); // it wil start application
}
}
2.7 Output:
Generate Token using http://localhost:8080/oauth/token

Spring boot OAuth2 JDBC token store example demo
oauth_refresh_token contains refresh tokens information

Spring boot OAuth2 Refresh Token Table
oauth_access_token contains access token information

Spring boot OAuth2 Access Token Table
3. Source Code
spring-boot-spring-security-auth2.0-authentication-server-example.zip

8 comments. Leave new
How can i get the Authorization in the headers? console is not showing this.
How can i add roles to dynamic user.
Hi Akanksha,
You can create custom UserServiceDetails to load dynamic load roles, Here is an example of OAuth2UserService : https://docs.spring.io/spring-security/site/docs/5.0.3.RELEASE/reference/htmlsingle/#oauth2login-advanced-map-authorities-oauth2userservice.
We will come back to you with example.
Thank you
I tried this example i am getting the below error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘securityConfig’: Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer@49a71302 to already built object
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans-4.
Hi,
This is very nice article and the solution you has given is working well. I have one question why you are storing client details in memory for class ClientDetailsServiceConfigurer? Also, for every user logged in will each use separate memory for client details in this case?
Thanks
Hi, from where I can download the whole project?
The source code is now available.
Getting Following Error
Field authenticationManager in com.example.demo.configuration.SecurityOAuth2Configuration required a bean of type ‘org.springframework.security.authentication.AuthenticationManager’ that could not be found.