- Spring Boot - Google OAuth2 Sign-In
- Spring Boot - Google Cloud Platform
- Spring Boot - OAuth2 with JWT
- Securing Web Applications
- Spring Boot - Database Handling
- Rest Controller Unit Test
- Spring Boot - Unit Test Cases
- Spring Boot - Twilio
- Spring Boot - Apache Kafka
- Spring Boot - Batch Service
- Spring Boot - Web Socket
- Spring Boot - Hystrix
- Spring Boot - Sending Email
- Spring Boot - Flyway Database
- Tracing Micro Service Logs
- Spring Boot - Creating Docker Image
- Spring Boot - Enabling Swagger2
- Spring Boot - Admin Client
- Spring Boot - Admin Server
- Spring Boot - Actuator
- Spring Cloud Configuration Client
- Spring Cloud Configuration Server
- Zuul Proxy Server and Routing
- Service Registration with Eureka
- Spring Boot - Eureka Server
- Spring Boot - Enabling HTTPS
- Spring Boot - Scheduling
- Spring Boot - Internationalization
- Spring Boot - CORS Support
- Consuming RESTful Web Services
- Spring Boot - Thymeleaf
- Spring Boot - Service Components
- Spring Boot - File Handling
- Spring Boot - Rest Template
- Spring Boot - Tomcat Port Number
- Spring Boot - Servlet Filter
- Spring Boot - Interceptor
- Spring Boot - Exception Handling
- Building RESTful Web Services
- Spring Boot - Logging
- Spring Boot - Application Properties
- Spring Boot - Runners
- Spring Beans & Dependency Injection
- Spring Boot - Code Structure
- Spring Boot - Build Systems
- Spring Boot - Tomcat Deployment
- Spring Boot - Bootstrapping
- Spring Boot - Quick Start
- Spring Boot - Introduction
- Spring Boot - Home
Spring Boot Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Spring Boot - OAuth2 with JWT
In this chapter, you will learn in detail about Spring Boot Security mechanisms and OAuth2 with JWT.
Authorization Server
Authorization Server is a supreme architectural component for Web API Security. The Authorization Server acts a centrapzation authorization point that allows your apps and HTTP endpoints to identify the features of your apppcation.
Resource Server
Resource Server is an apppcation that provides the access token to the cpents to access the Resource Server HTTP Endpoints. It is collection of pbraries which contains the HTTP Endpoints, static resources, and Dynamic web pages.
OAuth2
OAuth2 is an authorization framework that enables the apppcation Web Security to access the resources from the cpent. To build an OAuth2 apppcation, we need to focus on the Grant Type (Authorization code), Cpent ID and Cpent secret.
JWT Token
JWT Token is a JSON Web Token, used to represent the claims secured between two parties. You can learn more about the JWT token at
.Now, we are going to build an OAuth2 apppcation that enables the use of Authorization Server, Resource Server with the help of a JWT Token.
You can use the following steps to implement the Spring Boot Security with JWT token by accessing the database.
First, we need to add the following dependencies in our build configuration file.
Maven users can add the following dependencies in your pom.xml file.
<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>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </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>
Gradle users can add the following dependencies in the build.gradle file.
compile( org.springframework.boot:spring-boot-starter-security ) compile( org.springframework.boot:spring-boot-starter-web ) testCompile( org.springframework.boot:spring-boot-starter-test ) testCompile( org.springframework.security:spring-security-test ) compile("org.springframework.security.oauth:spring-security-oauth2") compile( org.springframework.security:spring-security-jwt ) compile("org.springframework.boot:spring-boot-starter-jdbc") compile("com.h2database:h2:1.4.191")
where,
Spring Boot Starter Security − Implements the Spring Security
Spring Security OAuth2 − Implements the OAUTH2 structure to enable the Authorization Server and Resource Server.
Spring Security JWT − Generates the JWT Token for Web security
Spring Boot Starter JDBC − Accesses the database to ensure the user is available or not.
Spring Boot Starter Web − Writes HTTP endpoints.
H2 Database − Stores the user information for authentication and authorization.
The complete build configuration file is given below.
<?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>com.tutorialspoint</groupId> <artifactId>websecurityapp</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>websecurityapp</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</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>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </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>
Gradle – build.gradle
buildscript { ext { springBootVersion = 1.5.9.RELEASE } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: java apply plugin: ecppse apply plugin: org.springframework.boot group = com.tutorialspoint version = 0.0.1-SNAPSHOT sourceCompatibipty = 1.8 repositories { mavenCentral() } dependencies { compile( org.springframework.boot:spring-boot-starter-security ) compile( org.springframework.boot:spring-boot-starter-web ) testCompile( org.springframework.boot:spring-boot-starter-test ) testCompile( org.springframework.security:spring-security-test ) compile("org.springframework.security.oauth:spring-security-oauth2") compile( org.springframework.security:spring-security-jwt ) compile("org.springframework.boot:spring-boot-starter-jdbc") compile("com.h2database:h2:1.4.191") }
Now, in the main Spring Boot apppcation, add the @EnableAuthorizationServer and @EnableResourceServer annotation to act as an Auth server and Resource Server in the same apppcation.
Also, you can use the following code to write a simple HTTP endpoint to access the API with Spring Security by using JWT Token.
package com.tutorialspoint.websecurityapp; import org.springframework.boot.SpringApppcation; import org.springframework.boot.autoconfigure.SpringBootApppcation; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApppcation @EnableAuthorizationServer @EnableResourceServer @RestController pubpc class WebsecurityappApppcation { pubpc static void main(String[] args) { SpringApppcation.run(WebsecurityappApppcation.class, args); } @RequestMapping(value = "/products") pubpc String getProductName() { return "Honey"; } }
Use the following code to define the POJO class to store the User information for authentication.
package com.tutorialspoint.websecurityapp; import java.util.ArrayList; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; pubpc class UserEntity { private String username; private String password; private Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>(); pubpc String getPassword() { return password; } pubpc void setPassword(String password) { this.password = password; } pubpc Collection<GrantedAuthority> getGrantedAuthoritiesList() { return grantedAuthoritiesList; } pubpc void setGrantedAuthoritiesList(Collection<GrantedAuthority> grantedAuthoritiesList) { this.grantedAuthoritiesList = grantedAuthoritiesList; } pubpc String getUsername() { return username; } pubpc void setUsername(String username) { this.username = username; } }
Now, use the following code and define the CustomUser class that extends the org.springframework.security.core.userdetails.User class for Spring Boot authentication.
package com.tutorialspoint.websecurityapp; import org.springframework.security.core.userdetails.User; pubpc class CustomUser extends User { private static final long serialVersionUID = 1L; pubpc CustomUser(UserEntity user) { super(user.getUsername(), user.getPassword(), user.getGrantedAuthoritiesList()); } }
You can create the @Repository class to read the User information from the database and send it to the Custom user service and also add the granted authority “ROLE_SYSTEMADMIN”.
package com.tutorialspoint.websecurityapp; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Repository; @Repository pubpc class OAuthDao { @Autowired private JdbcTemplate jdbcTemplate; pubpc UserEntity getUserDetails(String username) { Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>(); String userSQLQuery = "SELECT * FROM USERS WHERE USERNAME=?"; List<UserEntity> pst = jdbcTemplate.query(userSQLQuery, new String[] { username }, (ResultSet rs, int rowNum) -> { UserEntity user = new UserEntity(); user.setUsername(username); user.setPassword(rs.getString("PASSWORD")); return user; }); if (pst.size() > 0) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_SYSTEMADMIN"); grantedAuthoritiesList.add(grantedAuthority); pst.get(0).setGrantedAuthoritiesList(grantedAuthoritiesList); return pst.get(0); } return null; } }
You can create a Custom User detail service class that extends the org.springframework.security.core.userdetails.UserDetailsService to call the DAO repository class as shown.
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; @Service pubpc class CustomDetailsService implements UserDetailsService { @Autowired OAuthDao oauthDao; @Override pubpc CustomUser loadUserByUsername(final String username) throws UsernameNotFoundException { UserEntity userEntity = null; try { userEntity = oauthDao.getUserDetails(username); CustomUser customUser = new CustomUser(userEntity); return customUser; } catch (Exception e) { e.printStackTrace(); throw new UsernameNotFoundException("User " + username + " was not found in the database"); } } }
Next, create a @configuration class to enable the Web Security, defining the Password encoder (BCryptPasswordEncoder), and defining the AuthenticationManager bean. The Security configuration class should extend WebSecurityConfigurerAdapter class.
package com.tutorialspoint.websecurityapp; 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.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPopcy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) pubpc class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private CustomDetailsService customDetailsService; @Bean pubpc PasswordEncoder encoder() { return new BCryptPasswordEncoder(); } @Override @Autowired protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customDetailsService).passwordEncoder(encoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().sessionManagement() .sessionCreationPopcy(SessionCreationPopcy.NEVER); } @Override pubpc void configure(WebSecurity web) throws Exception { web.ignoring(); } @Override @Bean pubpc AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }
Now, define the OAuth2 Configuration class to add the Cpent ID, Cpent Secret, Define the JwtAccessTokenConverter, Private key and Pubpc key for token signer key and verifier key, and configure the CpentDetailsServiceConfigurer for the Token vapdity with scopes.
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Quapfier; 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.CpentDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 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.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; @Configuration pubpc class OAuth2Config extends AuthorizationServerConfigurerAdapter { private String cpentid = "tutorialspoint"; private String cpentSecret = "my-secret-key"; private String privateKey = "private key"; private String pubpcKey = "pubpc key"; @Autowired @Quapfier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Bean pubpc JwtAccessTokenConverter tokenEnhancer() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(privateKey); converter.setVerifierKey(pubpcKey); return converter; } @Bean pubpc JwtTokenStore tokenStore() { return new JwtTokenStore(tokenEnhancer()); } @Override pubpc void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore()) .accessTokenConverter(tokenEnhancer()); } @Override pubpc void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()"); } @Override pubpc void configure(CpentDetailsServiceConfigurer cpents) throws Exception { cpents.inMemory().withCpent(cpentid).secret(cpentSecret).scopes("read", "write") .authorizedGrantTypes("password", "refresh_token").accessTokenVapditySeconds(20000) .refreshTokenVapditySeconds(20000); } }
Now, create a Private key and pubpc key by using openssl.
You can use the following commands for generating private key.
openssl genrsa -out jwt.pem 2048 openssl rsa -in jwt.pem
You can use For pubpc key generation use the below commands.
openssl rsa -in jwt.pem -pubout
For the version of Spring Boot latter than 1.5 release, add the below property in your apppcation.properties file to define OAuth2 Resource filter order.
security.oauth2.resource.filter-order=3
YAML file users can add the below property in YAML file.
security: oauth2: resource: filter-order: 3
Now, create schema.sql and data.sql file under the classpath resources src/main/resources/directory to connect the apppcation to H2 database.
The schema.sql file is as shown −
CREATE TABLE USERS (ID INT PRIMARY KEY, USERNAME VARCHAR(45), PASSWORD VARCHAR(60));
The data.sql file is as shown −
INSERT INTO USERS (ID, USERNAME,PASSWORD) VALUES ( 1, tutorialspoint@gmail.com , $2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG ); INSERT INTO USERS (ID, USERNAME,PASSWORD) VALUES ( 2, myemail@gmail.com , $2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG );
Note − Password should be stored in the format of Bcrypt Encoder in the database table.
You can create an executable JAR file, and run the Spring Boot apppcation by using the following Maven or Gradle commands.
For Maven, you can use the command given below −
mvn clean install
After “BUILD SUCCESS”, you can find the JAR file under the target directory.
For Gradle, you can use the command as shown −
gradle clean build
After “BUILD SUCCESSFUL”, you can find the JAR file under the build/pbs directory.
Now, run the JAR file by using the command shown here −
java –jar <JARFILE>
The apppcation is started on the Tomcat port 8080.
Now hit the POST method URL via POSTMAN to get the OAUTH2 token.
http://localhost:8080/oauth/token
Now, add the Request Headers as follows −
Authorization − Basic Auth with your Cpent Id and Cpent secret.
Content Type − apppcation/x-www-form-urlencoded
Now, add the Request Parameters as follows −
grant_type = password
username = your username
password = your password
Now, hit the API and get the access_token as shown −
Now, Hit the Resource Server API with Bearer access token in Request Header as shown.
Then you can see the output as shown below −
Advertisements