├── README.md ├── pom.xml ├── spring-security-oauth2.iml └── src └── main ├── java └── com │ └── github │ └── handioq │ ├── Application.java │ ├── config │ ├── CustomUserDetailsService.java │ ├── OAuth2ServerConfiguration.java │ └── WebSecurityConfiguration.java │ ├── controller │ ├── GreetingController.java │ ├── HomeController.java │ └── UserController.java │ ├── model │ ├── Greeting.java │ ├── Role.java │ └── User.java │ └── repository │ └── UserRepository.java └── resources ├── application-https.properties ├── application.properties └── sql ├── import.sql ├── schema-oauth-mysql.sql └── schema.sql /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot based REST service with Spring Security OAuth2 2 | 3 | This is a simple REST service that provides a single RESTful endpoint protected by OAuth 2. 4 | 5 | ## How to build and run 6 | 7 | Just run with maven 8 | 9 | ``` 10 | mvn clean package spring-boot:run 11 | ``` 12 | 13 | ## How to use 14 | 15 | Open http://localhost:8080/greeting in your browser or some HTTP client (like a Postman). 16 | 17 | You receive the following JSON response, which indicates you are not authorized to access the resource: 18 | 19 | ``` 20 | { 21 | "error": "unauthorized", 22 | "error_description": "An Authentication object was not found in the SecurityContext" 23 | } 24 | ``` 25 | 26 | In order to access the protected resource, you must first request an access token via the OAuth. 27 | Request OAuth authorization: 28 | 29 | ``` 30 | curl -X POST -vu clientapp:123456 http://localhost:8080/oauth/token -H "Accept: application/json" -d "password=spring&username=admin&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp" 31 | ``` 32 | 33 | A successful authorization results in the following JSON response: 34 | 35 | ``` 36 | { 37 | "access_token": "ff16372e-38a7-4e29-88c2-1fb92897f558", 38 | "token_type": "bearer", 39 | "refresh_token": "f554d386-0b0a-461b-bdb2-292831cecd57", 40 | "expires_in": 43199, 41 | "scope": "read write" 42 | } 43 | ``` 44 | 45 | Use the access_token returned in the previous request to make the authorized request to the protected endpoint: 46 | 47 | ``` 48 | curl http://localhost:8080/greeting -H "Authorization: Bearer ff16372e-38a7-4e29-88c2-1fb92897f558" 49 | ``` 50 | 51 | If the request is successful, you will see the following JSON response: 52 | 53 | ``` 54 | { 55 | "id": 1, 56 | "content": "Hello, Roy!" 57 | } 58 | ``` 59 | 60 | After the specified time period, the access_token will expire. Use the refresh_token that was returned in the original OAuth authorization to retrieve a new access_token: 61 | 62 | ``` 63 | curl -X POST -vu clientapp:123456 http://localhost:8080/oauth/token -H "Accept: application/json" -d "grant_type=refresh_token&refresh_token=f554d386-0b0a-461b-bdb2-292831cecd57&client_secret=123456&client_id=clientapp" 64 | ``` 65 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | spring-security-oauth2 8 | spring-security-oauth2 9 | 1.0 10 | war 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-starter-parent 15 | 1.3.0.RC1 16 | 17 | 18 | 19 | 1.8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-security 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-data-jpa 34 | 35 | 36 | org.springframework.security.oauth 37 | spring-security-oauth2 38 | 39 | 40 | mysql 41 | mysql-connector-java 42 | 43 | 44 | org.hsqldb 45 | hsqldb 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-starter-tomcat 50 | provided 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-test 55 | test 56 | 57 | 58 | com.jayway.jsonpath 59 | json-path 60 | test 61 | 62 | 63 | com.jayway.jsonpath 64 | json-path-assert 65 | test 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-maven-plugin 74 | 75 | 76 | 77 | 78 | 79 | 80 | spring-releases 81 | https://repo.spring.io/libs-release 82 | 83 | 84 | 85 | 86 | 87 | spring-plugin-releases 88 | https://repo.spring.io/plugins-release 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /spring-security-oauth2.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 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/Application.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq; 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/github/handioq/config/CustomUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.config; 2 | 3 | import com.github.handioq.model.User; 4 | import com.github.handioq.repository.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.core.GrantedAuthority; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.security.core.userdetails.UserDetailsService; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.Collection; 13 | 14 | @Service 15 | public class CustomUserDetailsService implements UserDetailsService { 16 | 17 | private final UserRepository userRepository; 18 | 19 | @Autowired 20 | public CustomUserDetailsService(UserRepository userRepository) { 21 | this.userRepository = userRepository; 22 | } 23 | 24 | @Override 25 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 26 | User user = userRepository.findByLogin(username); 27 | if (user == null) { 28 | throw new UsernameNotFoundException(String.format("User %s does not exist!", username)); 29 | } 30 | return new UserRepositoryUserDetails(user); 31 | } 32 | 33 | private final static class UserRepositoryUserDetails extends User implements UserDetails { 34 | 35 | private static final long serialVersionUID = 1L; 36 | 37 | private UserRepositoryUserDetails(User user) { 38 | super(user); 39 | } 40 | 41 | @Override 42 | public Collection getAuthorities() { 43 | return getRoles(); 44 | } 45 | 46 | @Override 47 | public String getUsername() { 48 | return getLogin(); 49 | } 50 | 51 | @Override 52 | public boolean isAccountNonExpired() { 53 | return true; 54 | } 55 | 56 | @Override 57 | public boolean isAccountNonLocked() { 58 | return true; 59 | } 60 | 61 | @Override 62 | public boolean isCredentialsNonExpired() { 63 | return true; 64 | } 65 | 66 | @Override 67 | public boolean isEnabled() { 68 | return true; 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/config/OAuth2ServerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.github.handioq.config; 18 | 19 | import org.springframework.beans.factory.annotation.Autowired; 20 | import org.springframework.beans.factory.annotation.Qualifier; 21 | import org.springframework.context.annotation.Bean; 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.context.annotation.Primary; 24 | import org.springframework.security.authentication.AuthenticationManager; 25 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 26 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 27 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 28 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 29 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 30 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 31 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 32 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 33 | import org.springframework.security.oauth2.provider.token.DefaultTokenServices; 34 | import org.springframework.security.oauth2.provider.token.TokenStore; 35 | import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; 36 | 37 | @Configuration 38 | public class OAuth2ServerConfiguration { 39 | 40 | private static final String RESOURCE_ID = "restservice"; 41 | 42 | @Configuration 43 | @EnableResourceServer 44 | protected static class ResourceServerConfiguration extends 45 | ResourceServerConfigurerAdapter { 46 | 47 | @Override 48 | public void configure(ResourceServerSecurityConfigurer resources) { 49 | resources 50 | .resourceId(RESOURCE_ID); 51 | } 52 | 53 | @Override 54 | public void configure(HttpSecurity http) throws Exception { 55 | http 56 | .authorizeRequests() 57 | .antMatchers("/users").hasRole("ADMIN") 58 | .antMatchers("/greeting").authenticated(); 59 | } 60 | 61 | } 62 | 63 | @Configuration 64 | @EnableAuthorizationServer 65 | protected static class AuthorizationServerConfiguration extends 66 | AuthorizationServerConfigurerAdapter { 67 | 68 | private TokenStore tokenStore = new InMemoryTokenStore(); 69 | 70 | @Autowired 71 | @Qualifier("authenticationManagerBean") 72 | private AuthenticationManager authenticationManager; 73 | 74 | @Autowired 75 | private CustomUserDetailsService userDetailsService; 76 | 77 | @Override 78 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) 79 | throws Exception { 80 | endpoints 81 | .tokenStore(this.tokenStore) 82 | .authenticationManager(this.authenticationManager) 83 | .userDetailsService(userDetailsService); 84 | } 85 | 86 | @Override 87 | public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 88 | clients 89 | .inMemory() 90 | .withClient("clientapp") 91 | .authorizedGrantTypes("password", "refresh_token") 92 | .authorities("USER") 93 | .scopes("read", "write") 94 | .resourceIds(RESOURCE_ID) 95 | .secret("123456"); 96 | } 97 | 98 | @Bean 99 | @Primary 100 | public DefaultTokenServices tokenServices() { 101 | DefaultTokenServices tokenServices = new DefaultTokenServices(); 102 | tokenServices.setSupportRefreshToken(true); 103 | tokenServices.setTokenStore(this.tokenStore); 104 | return tokenServices; 105 | } 106 | 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/config/WebSecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.authentication.AuthenticationManager; 7 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | 12 | @Configuration 13 | @EnableWebSecurity 14 | public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 15 | 16 | @Autowired 17 | private UserDetailsService userDetailsService; 18 | 19 | @Override 20 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 21 | auth.userDetailsService(userDetailsService); 22 | } 23 | 24 | @Override 25 | @Bean 26 | public AuthenticationManager authenticationManagerBean() throws Exception { 27 | return super.authenticationManagerBean(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/controller/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.controller; 2 | 3 | import com.github.handioq.model.Greeting; 4 | import com.github.handioq.model.User; 5 | import org.springframework.security.core.annotation.AuthenticationPrincipal; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import java.util.concurrent.atomic.AtomicLong; 10 | 11 | @RestController 12 | public class GreetingController { 13 | 14 | private static final String template = "Hello, %s!"; 15 | 16 | private final AtomicLong counter = new AtomicLong(); 17 | 18 | @RequestMapping("/greeting") 19 | public Greeting greeting(@AuthenticationPrincipal User user) { 20 | return new Greeting(counter.incrementAndGet(), 21 | String.format(template, user.getName())); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/controller/HomeController.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class HomeController { 8 | 9 | @RequestMapping("/") 10 | public String home() { 11 | return "home"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.controller; 2 | 3 | import com.github.handioq.model.User; 4 | import com.github.handioq.repository.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @RestController 10 | public class UserController { 11 | 12 | private final UserRepository userRepository; 13 | 14 | @Autowired 15 | public UserController(UserRepository userRepository) { 16 | this.userRepository = userRepository; 17 | } 18 | 19 | @RequestMapping("/users") 20 | public Iterable getUsers() { 21 | return userRepository.findAll(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/model/Greeting.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.model; 2 | 3 | public class Greeting { 4 | 5 | private final long id; 6 | 7 | private final String content; 8 | 9 | public long getId() { 10 | return id; 11 | } 12 | 13 | public String getContent() { 14 | return content; 15 | } 16 | 17 | public Greeting(long id, String content) { 18 | this.id = id; 19 | this.content = content; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/model/Role.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import org.hibernate.validator.constraints.NotEmpty; 5 | import org.springframework.security.core.GrantedAuthority; 6 | 7 | import javax.persistence.*; 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | @Entity 12 | public class Role implements GrantedAuthority { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.AUTO) 18 | private Integer id; 19 | 20 | @NotEmpty 21 | private String name; 22 | 23 | @JsonIgnore 24 | @ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles") 25 | private Set users = new HashSet(); 26 | 27 | @Override 28 | public String getAuthority() { 29 | return name; 30 | } 31 | 32 | public Integer getId() { 33 | return id; 34 | } 35 | 36 | public void setId(Integer id) { 37 | this.id = id; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | public Set getUsers() { 49 | return users; 50 | } 51 | 52 | public void setUsers(Set users) { 53 | this.users = users; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/model/User.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import org.hibernate.validator.constraints.NotEmpty; 5 | 6 | import javax.persistence.*; 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | @Entity 11 | public class User { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.AUTO) 15 | private Integer id; 16 | 17 | @NotEmpty 18 | private String name; 19 | 20 | @NotEmpty 21 | @Column(unique = true, nullable = false) 22 | private String login; 23 | 24 | @NotEmpty 25 | private String password; 26 | 27 | @JsonIgnore 28 | @ManyToMany(fetch = FetchType.EAGER) 29 | @JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") }) 30 | private Set roles = new HashSet(); 31 | 32 | public User() { 33 | } 34 | 35 | public User(User user) { 36 | super(); 37 | this.id = user.getId(); 38 | this.name = user.getName(); 39 | this.login = user.getLogin(); 40 | this.password = user.getPassword(); 41 | this.roles = user.getRoles(); 42 | } 43 | 44 | public Integer getId() { 45 | return id; 46 | } 47 | 48 | public void setId(Integer id) { 49 | this.id = id; 50 | } 51 | 52 | public String getName() { 53 | return name; 54 | } 55 | 56 | public void setName(String name) { 57 | this.name = name; 58 | } 59 | 60 | public String getLogin() { 61 | return login; 62 | } 63 | 64 | public void setLogin(String login) { 65 | this.login = login; 66 | } 67 | 68 | public String getPassword() { 69 | return password; 70 | } 71 | 72 | public void setPassword(String password) { 73 | this.password = password; 74 | } 75 | 76 | public Set getRoles() { 77 | return roles; 78 | } 79 | 80 | public void setRoles(Set roles) { 81 | this.roles = roles; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/github/handioq/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.github.handioq.repository; 2 | 3 | import com.github.handioq.model.User; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | public interface UserRepository extends CrudRepository { 7 | 8 | User findByLogin(String login); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/application-https.properties: -------------------------------------------------------------------------------- 1 | # Configure the server to run with SSL/TLS and using HTTPS 2 | server.port = 8443 3 | server.ssl.key-store = classpath:keystore.jks 4 | server.ssl.key-store-password = password 5 | server.ssl.key-password = password -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.profiles.active=dev 2 | #comment above dev profile and uncomment line below to operate using https 3 | #spring.profiles.active=https 4 | 5 | spring.datasource.url = jdbc:mysql://localhost:3306/shop_oauth 6 | spring.datasource.username = root 7 | spring.datasource.password = root 8 | spring.datasource.driverClassName = com.mysql.jdbc.Driver 9 | 10 | #spring.datasource.initialize=true 11 | #spring.datasource.init-sql=classpath:*schema.sql 12 | #spring.datasource.data=classpath:*import.sql 13 | 14 | #spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect 15 | 16 | #spring.jpa.hibernate.ddl-auto=update 17 | #spring.jpa.show-sql = true -------------------------------------------------------------------------------- /src/main/resources/sql/import.sql: -------------------------------------------------------------------------------- 1 | insert into user(id, name, login, password) values (1,'Admin','admin','spring'); 2 | insert into user(id, name, login, password) values (2,'User','user','spring'); 3 | 4 | insert into role(id, name) values (1,'ROLE_USER'); 5 | insert into role(id, name) values (2,'ROLE_ADMIN'); 6 | insert into role(id, name) values (3,'ROLE_GUEST'); 7 | 8 | insert into user_role(user_id, role_id) values (1,1); 9 | insert into user_role(user_id, role_id) values (1,2); 10 | insert into user_role(user_id, role_id) values (2,1); 11 | -------------------------------------------------------------------------------- /src/main/resources/sql/schema-oauth-mysql.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS user (id BIGINT PRIMARY KEY, name VARCHAR(50), login VARCHAR(50), password VARCHAR(50)); 2 | CREATE TABLE IF NOT EXISTS role (id BIGINT PRIMARY KEY, name VARCHAR(50)); 3 | CREATE TABLE IF NOT EXISTS user_role (user_id BIGINT NOT NULL,role_id BIGINT NOT NULL); 4 | 5 | -- for oauth data 6 | create table IF NOT EXISTS oauth_client_details ( 7 | client_id VARCHAR(256) PRIMARY KEY, 8 | resource_ids VARCHAR(256), 9 | client_secret VARCHAR(256), 10 | scope VARCHAR(256), 11 | authorized_grant_types VARCHAR(256), 12 | web_server_redirect_uri VARCHAR(256), 13 | authorities VARCHAR(256), 14 | access_token_validity INTEGER, 15 | refresh_token_validity INTEGER, 16 | additional_information VARCHAR(4096), 17 | autoapprove VARCHAR(256) 18 | ); 19 | 20 | create table IF NOT EXISTS oauth_client_token ( 21 | token_id VARCHAR(256), 22 | token BLOB, 23 | authentication_id VARCHAR(256) PRIMARY KEY, 24 | user_name VARCHAR(256), 25 | client_id VARCHAR(256) 26 | ); 27 | 28 | create table IF NOT EXISTS oauth_access_token ( 29 | token_id VARCHAR(256), 30 | token BLOB, 31 | authentication_id VARCHAR(256) PRIMARY KEY, 32 | user_name VARCHAR(256), 33 | client_id VARCHAR(256), 34 | authentication BLOB, 35 | refresh_token VARCHAR(256) 36 | ); 37 | 38 | create table IF NOT EXISTS oauth_refresh_token ( 39 | token_id VARCHAR(256), 40 | token BLOB, 41 | authentication BLOB 42 | ); 43 | 44 | create table IF NOT EXISTS oauth_code ( 45 | code VARCHAR(256), authentication BLOB 46 | ); 47 | 48 | create table IF NOT EXISTS oauth_approvals ( 49 | userId VARCHAR(256), 50 | clientId VARCHAR(256), 51 | scope VARCHAR(256), 52 | status VARCHAR(10), 53 | expiresAt TIMESTAMP, 54 | lastModifiedAt TIMESTAMP 55 | ); -------------------------------------------------------------------------------- /src/main/resources/sql/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS user (id BIGINT PRIMARY KEY, name VARCHAR(50), login VARCHAR(50), password VARCHAR(50)); 2 | CREATE TABLE IF NOT EXISTS role (id BIGINT PRIMARY KEY, name VARCHAR(50)); 3 | CREATE TABLE IF NOT EXISTS user_role (user_id BIGINT NOT NULL,role_id BIGINT NOT NULL); 4 | 5 | -- if u want use jdbc tokenstore, than use schema-oauth-mysql.sql --------------------------------------------------------------------------------