├── README.md ├── pom.xml ├── spring-boot-security-oauth2-example.iml └── src └── main ├── java └── com │ └── devglan │ ├── Application.java │ ├── config │ ├── AuthorizationServerConfig.java │ ├── ResourceServerConfig.java │ └── SecurityConfig.java │ ├── controller │ └── UserController.java │ ├── dao │ └── UserDao.java │ ├── model │ └── User.java │ └── service │ ├── UserService.java │ └── impl │ └── UserServiceImpl.java └── resources └── application.properties /README.md: -------------------------------------------------------------------------------- 1 | # spring-boot-security-oauth2 2 | This article aims to provide a working example of spring boot security oauth2. To ge started with this project just checkout the project 3 | and set up the database configuration as per application.properties and run Application.java as a java application and you are done. 4 | The complete explanation is provided on my blog - [spring security oauth2 example](http://www.devglan.com/spring-security/spring-boot-security-oauth2-example) 5 | This project uses 6 | 1. Spring Boot 1.5.8.RELEASE 7 | 2. Java 8 8 | 3. MySql 9 | 10 | Visit [spring security](http://www.devglan.com/tutorial/topics/spring-security) for other similar articles on spring security. 11 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.devglan 8 | spring-boot-security-oauth2-example 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 1.5.8.RELEASE 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-jpa 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-security 29 | 30 | 31 | org.springframework.security.oauth 32 | spring-security-oauth2 33 | 34 | 35 | mysql 36 | mysql-connector-java 37 | 38 | 39 | commons-dbcp 40 | commons-dbcp 41 | 42 | 43 | 44 | 45 | 1.8 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-maven-plugin 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /spring-boot-security-oauth2-example.iml: -------------------------------------------------------------------------------- 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 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/main/java/com/devglan/Application.java: -------------------------------------------------------------------------------- 1 | package com.devglan; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(Application.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/devglan/config/AuthorizationServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.devglan.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.authentication.AuthenticationManager; 6 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 7 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 8 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 9 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 10 | import org.springframework.security.oauth2.provider.token.TokenStore; 11 | 12 | @Configuration 13 | @EnableAuthorizationServer 14 | public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { 15 | 16 | static final String CLIEN_ID = "devglan-client"; 17 | static final String CLIENT_SECRET = "devglan-secret"; 18 | static final String GRANT_TYPE_PASSWORD = "password"; 19 | static final String AUTHORIZATION_CODE = "authorization_code"; 20 | static final String REFRESH_TOKEN = "refresh_token"; 21 | static final String IMPLICIT = "implicit"; 22 | static final String SCOPE_READ = "read"; 23 | static final String SCOPE_WRITE = "write"; 24 | static final String TRUST = "trust"; 25 | static final int ACCESS_TOKEN_VALIDITY_SECONDS = 1*60*60; 26 | static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 6*60*60; 27 | 28 | @Autowired 29 | private TokenStore tokenStore; 30 | 31 | @Autowired 32 | private AuthenticationManager authenticationManager; 33 | 34 | @Override 35 | public void configure(ClientDetailsServiceConfigurer configurer) throws Exception { 36 | 37 | configurer 38 | .inMemory() 39 | .withClient(CLIEN_ID) 40 | .secret(CLIENT_SECRET) 41 | .authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT ) 42 | .scopes(SCOPE_READ, SCOPE_WRITE, TRUST) 43 | .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS). 44 | refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS); 45 | } 46 | 47 | @Override 48 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 49 | endpoints.tokenStore(tokenStore) 50 | .authenticationManager(authenticationManager); 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/com/devglan/config/ResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.devglan.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 7 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 8 | import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; 9 | 10 | @Configuration 11 | @EnableResourceServer 12 | public class ResourceServerConfig extends ResourceServerConfigurerAdapter { 13 | 14 | private static final String RESOURCE_ID = "resource_id"; 15 | 16 | @Override 17 | public void configure(ResourceServerSecurityConfigurer resources) { 18 | resources.resourceId(RESOURCE_ID).stateless(false); 19 | } 20 | 21 | @Override 22 | public void configure(HttpSecurity http) throws Exception { 23 | http. 24 | anonymous().disable() 25 | .authorizeRequests() 26 | .antMatchers("/users/**").access("hasRole('ADMIN')") 27 | .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/com/devglan/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.devglan.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.authentication.AuthenticationManager; 8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 13 | import org.springframework.security.core.userdetails.UserDetailsService; 14 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 15 | import org.springframework.security.oauth2.provider.token.TokenStore; 16 | import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; 17 | import org.springframework.web.cors.CorsConfiguration; 18 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 19 | import org.springframework.web.filter.CorsFilter; 20 | 21 | import javax.annotation.Resource; 22 | 23 | @Configuration 24 | @EnableWebSecurity 25 | @EnableGlobalMethodSecurity(prePostEnabled = true) 26 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 27 | 28 | @Resource(name = "userService") 29 | private UserDetailsService userDetailsService; 30 | 31 | @Override 32 | @Bean 33 | public AuthenticationManager authenticationManagerBean() throws Exception { 34 | return super.authenticationManagerBean(); 35 | } 36 | 37 | @Autowired 38 | public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { 39 | auth.userDetailsService(userDetailsService) 40 | .passwordEncoder(encoder()); 41 | } 42 | 43 | @Override 44 | protected void configure(HttpSecurity http) throws Exception { 45 | http 46 | .csrf().disable() 47 | .anonymous().disable() 48 | .authorizeRequests() 49 | .antMatchers("/api-docs/**").permitAll(); 50 | } 51 | 52 | @Bean 53 | public TokenStore tokenStore() { 54 | return new InMemoryTokenStore(); 55 | } 56 | 57 | @Bean 58 | public BCryptPasswordEncoder encoder(){ 59 | return new BCryptPasswordEncoder(); 60 | } 61 | 62 | @Bean 63 | public FilterRegistrationBean corsFilter() { 64 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 65 | CorsConfiguration config = new CorsConfiguration(); 66 | config.setAllowCredentials(true); 67 | config.addAllowedOrigin("*"); 68 | config.addAllowedHeader("*"); 69 | config.addAllowedMethod("*"); 70 | source.registerCorsConfiguration("/**", config); 71 | FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); 72 | bean.setOrder(0); 73 | return bean; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/devglan/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.devglan.controller; 2 | 3 | import com.devglan.model.User; 4 | import com.devglan.service.UserService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import java.util.List; 10 | 11 | @RestController 12 | @RequestMapping("/users") 13 | public class UserController { 14 | 15 | @Autowired 16 | private UserService userService; 17 | 18 | @RequestMapping(value="/user", method = RequestMethod.GET) 19 | public List listUser(){ 20 | return userService.findAll(); 21 | } 22 | 23 | @RequestMapping(value = "/user", method = RequestMethod.POST) 24 | public User create(@RequestBody User user){ 25 | return userService.save(user); 26 | } 27 | 28 | @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE) 29 | public String delete(@PathVariable(value = "id") Long id){ 30 | userService.delete(id); 31 | return "success"; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/devglan/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.devglan.dao; 2 | 3 | import com.devglan.model.User; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface UserDao extends CrudRepository { 9 | User findByUsername(String username); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/devglan/model/User.java: -------------------------------------------------------------------------------- 1 | package com.devglan.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | 5 | import javax.persistence.*; 6 | 7 | @Entity 8 | public class User { 9 | 10 | @Id 11 | @GeneratedValue(strategy= GenerationType.AUTO) 12 | private long id; 13 | @Column 14 | private String username; 15 | @Column 16 | @JsonIgnore 17 | private String password; 18 | @Column 19 | private long salary; 20 | @Column 21 | private int age; 22 | 23 | public long getId() { 24 | return id; 25 | } 26 | 27 | public void setId(long id) { 28 | this.id = id; 29 | } 30 | 31 | public String getUsername() { 32 | return username; 33 | } 34 | 35 | public void setUsername(String username) { 36 | this.username = username; 37 | } 38 | 39 | public String getPassword() { 40 | return password; 41 | } 42 | 43 | public void setPassword(String password) { 44 | this.password = password; 45 | } 46 | 47 | public long getSalary() { 48 | return salary; 49 | } 50 | 51 | public void setSalary(long salary) { 52 | this.salary = salary; 53 | } 54 | 55 | public int getAge() { 56 | return age; 57 | } 58 | 59 | public void setAge(int age) { 60 | this.age = age; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/devglan/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.devglan.service; 2 | 3 | import com.devglan.model.User; 4 | 5 | import java.util.List; 6 | 7 | public interface UserService { 8 | 9 | User save(User user); 10 | List findAll(); 11 | void delete(long id); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/devglan/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.devglan.service.impl; 2 | 3 | import com.devglan.dao.UserDao; 4 | import com.devglan.model.User; 5 | import com.devglan.service.UserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.core.userdetails.UserDetailsService; 10 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.List; 17 | 18 | 19 | @Service(value = "userService") 20 | public class UserServiceImpl implements UserDetailsService, UserService { 21 | 22 | @Autowired 23 | private UserDao userDao; 24 | 25 | public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { 26 | User user = userDao.findByUsername(userId); 27 | if(user == null){ 28 | throw new UsernameNotFoundException("Invalid username or password."); 29 | } 30 | return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthority()); 31 | } 32 | 33 | private List getAuthority() { 34 | return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN")); 35 | } 36 | 37 | public List findAll() { 38 | List list = new ArrayList<>(); 39 | userDao.findAll().iterator().forEachRemaining(list::add); 40 | return list; 41 | } 42 | 43 | @Override 44 | public void delete(long id) { 45 | userDao.delete(id); 46 | } 47 | 48 | @Override 49 | public User save(User user) { 50 | return userDao.save(user); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/test 2 | spring.datasource.username=root 3 | spring.datasource.password=root 4 | spring.jpa.hibernate.ddl-auto=update 5 | spring.jpa.show-sql=true 6 | spring.user.datasource.driver-class-name=com.mysql.jdbc.Driver 7 | security.oauth2.resource.filter-order=3 --------------------------------------------------------------------------------