├── 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
--------------------------------------------------------------------------------