Spring Boot Oauth2 Implementation using MYSQL Database
Purpose: In this post, we will learn how we can implement Oauth2. The steps are given below.
1. Setup and Create Project: Visit here. Spring Boot Rest API Hello World Examples.
Next Step. Spring Boot Parent Dependencies.
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.6.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent>
Next Step. MSQL Database Dependencies.
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>
Next Step. Oauth2 and JWT Token dependency Dependencies.
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-jwt</artifactId><version>1.0.9.RELEASE</version></dependency><dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.6.RELEASE</version></dependency>
Next Step. Spring Boot main class.
Class: Application.java
Note: @SpringBootApplication=@Configuration+ @EnableAutoConfiguration+ @ComponentScan.
package com.bce;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
Next Step. Create Rest Controller.
package com.bce.contoller;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpHeaders;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RestController;import com.bce.model.UserInfo;import com.bce.service.UserInfoService;@RestControllerpublic class UserController {@Autowiredprivate UserInfoService userService;@GetMapping("/user/get")public List<UserInfo> getAllUser(@RequestHeader HttpHeaders requestHeader) {List<UserInfo> userInfos = userService.getAllActiveUserInfo();return userInfos;}@PostMapping("/user")public UserInfo addUser(@RequestBody UserInfo userRecord) {return userService.addUser(userRecord);}}
In above controller we have two API in which BASE_URL/user is accessible without authentication and BASE_URL/user/get is accessible with authentication.
Next Step. Add below line in application.properties for MYSQL and Oauth2 configuration.
#server PORTserver.port=8081# DataSource settings: set here your own configurations for the database# connection. In this example we have "dojsb" as database name and# "root" as username and password.spring.datasource.url = jdbc:mysql://127.0.0.1:3306/oauthspring.datasource.username = rootspring.datasource.password = root# Hibernate ddl auto (create, create-drop, update)spring.jpa.hibernate.ddl-auto = update# Naming strategyspring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy# Use spring.jpa.properties.* for Hibernate native properties (the prefix is# stripped before adding them to the entity manager)# The SQL dialect makes Hibernate generate better SQL for the chosen databasespring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialectspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver#################### SECURITY CONFIG #########Application specific : Note: Change client id and Secret keyauthentication.oauth.clientid=springbootrestauthentication.oauth.secret=restserviceauthentication.oauth.tokenValidityInSeconds=6000authentication.oauth.refreshTokenValidityInSeconds=10000authentication.oauth.grant.type=passwordauthentication.oauth.grant.refresh.type=refresh_token
Next Step. OAuth Configuration add below java file (OAuthConfiguration.java)
package com.bce.configuration;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.factory.PasswordEncoderFactories;import org.springframework.security.crypto.password.PasswordEncoder;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.JwtAccessTokenConverter;import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;@Configuration@EnableAuthorizationServerpublic class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {@Value("${authentication.oauth.clientid:clientid}")private String PROP_CLIENTID;@Value("${authentication.oauth.secret:secret}")private String PROP_SECRET;@Value("${authentication.oauth.tokenValidityInSeconds:60}")private Integer PROP_TOKEN_VALIDITY_SECONDS;@Value("${authentication.oauth.refreshTokenValidityInSeconds:120}")private Integer PROP_REFRESH_TOKEN_VALIDITY_SECONDS;@Autowired@Qualifier("authenticationManagerBean")private AuthenticationManager authenticationManager;@AutowiredUserDetailsService userDetailsService;@Overridepublic void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}@Beanpublic PasswordEncoder passwordEncoder() {return PasswordEncoderFactories.createDelegatingPasswordEncoder();}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient(PROP_CLIENTID).secret(passwordEncoder().encode(PROP_SECRET)).authorizedGrantTypes("password", "authorization_code", "refresh_token").scopes("read","write").authorities("USER","ADMIN").autoApprove(true).accessTokenValiditySeconds(PROP_TOKEN_VALIDITY_SECONDS).refreshTokenValiditySeconds(PROP_REFRESH_TOKEN_VALIDITY_SECONDS);}@Overridepublic void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).accessTokenConverter(defaultAccessTokenConverter()).userDetailsService(userDetailsService);}@Beanpublic TokenStore tokenStore(){return new JwtTokenStore(defaultAccessTokenConverter());}@Beanpublic JwtAccessTokenConverter defaultAccessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey("123");return converter;}}
Next Step. OAuth Configuration add below java file (SecurityConfig.java)
package com.bce.configuration;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.authentication.dao.DaoAuthenticationProvider;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.WebSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import com.bce.service.UserDetailsServiceImpl;@EnableWebSecurity@EnableGlobalMethodSecurity(securedEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredUserDetailsServiceImpl userDetailsService;@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/pages/");}@Beanpublic DaoAuthenticationProvider authenticationProvider() {DaoAuthenticationProvider provider = new DaoAuthenticationProvider();provider.setPasswordEncoder(bCryptPasswordEncoder());provider.setUserDetailsService(userDetailsService);return provider;}@Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder() {return new BCryptPasswordEncoder();}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {auth.authenticationProvider(authenticationProvider());}}
Next Step: add ResourceServerConfiguration.java file.
package com.bce.configuration;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;@Configuration@EnableResourceServerpublic class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {private static final String RESOURCE_ID = "oauth2-api";@Overridepublic void configure(ResourceServerSecurityConfigurer resources) {resources.resourceId(RESOURCE_ID);}@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/", "/user", "/oauth/token").permitAll();http.csrf().disable();http.antMatcher("/**").authorizeRequests().anyRequest().authenticated();}}
Next Step. Get all users without authentication token.
Next Step. Generate access token using below url. Username=client id and password=secret which is define in application properties.
Download Code from GitHub. Download
No comments:
Post a Comment