

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.