├── .gitignore
├── LICENSE
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── dazito
│ │ └── oauthexample
│ │ ├── OauthExampleApplication.java
│ │ ├── config
│ │ └── AppConfig.java
│ │ ├── entities
│ │ └── Account.java
│ │ ├── oauth
│ │ └── AuthServerOAuth2Config.java
│ │ ├── repository
│ │ └── AccountRepository.java
│ │ ├── resource
│ │ └── PrincipalResource.java
│ │ └── service
│ │ └── AccountUserDetailsService.java
└── resources
│ ├── application.properties
│ ├── data.sql
│ └── schema.sql
└── test
└── java
└── com
└── dazito
└── oauthexample
└── OauthExampleApplicationTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 | mvnw
24 | mvnw.cmd
25 | *.iml
26 | .idea/
27 | .mvn/
28 | target/
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Pedro M.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.dazito
7 | oauth-example
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | oauth-example
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 1.5.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 | Dalston.SR1
26 |
27 |
28 |
29 |
30 | org.springframework.cloud
31 | spring-cloud-starter-oauth2
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-data-jpa
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-web
40 |
41 |
42 | mysql
43 | mysql-connector-java
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 | test
50 |
51 |
52 |
53 |
54 |
55 |
56 | org.springframework.cloud
57 | spring-cloud-dependencies
58 | ${spring-cloud.version}
59 | pom
60 | import
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.springframework.boot
69 | spring-boot-maven-plugin
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/main/java/com/dazito/oauthexample/OauthExampleApplication.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
6 |
7 | @EnableResourceServer
8 | @SpringBootApplication
9 | public class OauthExampleApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(OauthExampleApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/dazito/oauthexample/config/AppConfig.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.jdbc.datasource.DriverManagerDataSource;
7 | import org.springframework.security.oauth2.provider.token.TokenStore;
8 | import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
9 |
10 | import javax.sql.DataSource;
11 |
12 | /**
13 | * Created by daz on 01/07/2017.
14 | */
15 | @Configuration
16 | public class AppConfig {
17 |
18 | @Value("${spring.datasource.url}")
19 | private String datasourceUrl;
20 |
21 | @Value("${spring.database.driverClassName}")
22 | private String dbDriverClassName;
23 |
24 | @Value("${spring.datasource.username}")
25 | private String dbUsername;
26 |
27 | @Value("${spring.datasource.password}")
28 | private String dbPassword;
29 |
30 | @Bean
31 | public DataSource dataSource() {
32 | final DriverManagerDataSource dataSource = new DriverManagerDataSource();
33 |
34 | dataSource.setDriverClassName(dbDriverClassName);
35 | dataSource.setUrl(datasourceUrl);
36 | dataSource.setUsername(dbUsername);
37 | dataSource.setPassword(dbPassword);
38 |
39 | return dataSource;
40 | }
41 |
42 | @Bean
43 | public TokenStore tokenStore() {
44 | return new JdbcTokenStore(dataSource());
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/dazito/oauthexample/entities/Account.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample.entities;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.Entity;
5 | import javax.persistence.GeneratedValue;
6 | import javax.persistence.Id;
7 |
8 | /**
9 | * Created by daz on 29/06/2017.
10 | */
11 | @Entity
12 | public class Account {
13 |
14 | @Id
15 | @GeneratedValue
16 | private Long id;
17 | @Column(name = "username", length = 128)
18 | private String username;
19 | @Column(name = "password", length = 128)
20 | private String password;
21 |
22 | public Account() {
23 | }
24 |
25 | public Account(String username, String password) {
26 |
27 | this.username = username;
28 | this.password = password;
29 | }
30 |
31 | public Long getId() {
32 | return id;
33 | }
34 |
35 | public void setId(Long id) {
36 | this.id = id;
37 | }
38 |
39 | public String getUsername() {
40 | return username;
41 | }
42 |
43 | public void setUsername(String username) {
44 | this.username = username;
45 | }
46 |
47 | public String getPassword() {
48 | return password;
49 | }
50 |
51 | public void setPassword(String password) {
52 | this.password = password;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/dazito/oauthexample/oauth/AuthServerOAuth2Config.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample.oauth;
2 |
3 | import com.dazito.oauthexample.config.AppConfig;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.security.authentication.AuthenticationManager;
7 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
8 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
9 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
10 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
11 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
12 |
13 | /**
14 | * Created by daz on 27/06/2017.
15 | */
16 | @EnableAuthorizationServer
17 | @Configuration
18 | public class AuthServerOAuth2Config extends AuthorizationServerConfigurerAdapter {
19 |
20 | private final AuthenticationManager authenticationManager;
21 | private final AppConfig appConfig;
22 |
23 | @Autowired
24 | public AuthServerOAuth2Config(AuthenticationManager authenticationManager, AppConfig appConfig) {
25 | this.authenticationManager = authenticationManager;
26 | this.appConfig = appConfig;
27 | }
28 |
29 | @Override
30 | public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
31 | clients.jdbc(appConfig.dataSource());
32 | }
33 |
34 | @Override
35 | public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
36 | /*
37 | * Allow our tokens to be delivered from our token access point as well as for tokens
38 | * to be validated from this point
39 | */
40 | security.checkTokenAccess("permitAll()");
41 | }
42 |
43 | @Override
44 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
45 | endpoints
46 | .authenticationManager(authenticationManager)
47 | .tokenStore(appConfig.tokenStore()); // Persist the tokens in the database
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/dazito/oauthexample/repository/AccountRepository.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample.repository;
2 |
3 | import com.dazito.oauthexample.entities.Account;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 |
6 | import java.util.Optional;
7 |
8 | /**
9 | * Created by daz on 29/06/2017.
10 | */
11 | public interface AccountRepository extends JpaRepository {
12 |
13 | Optional findByUsername(String username);
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/dazito/oauthexample/resource/PrincipalResource.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample.resource;
2 |
3 | import org.springframework.web.bind.annotation.RequestMapping;
4 | import org.springframework.web.bind.annotation.RequestMethod;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | import java.security.Principal;
8 |
9 | /**
10 | * Created by daz on 29/06/2017.
11 | */
12 | @RestController
13 | @RequestMapping(path = "/account")
14 | public class PrincipalResource {
15 |
16 | @RequestMapping(method = RequestMethod.POST)
17 | public Principal oauth(Principal principal) {
18 | /*
19 | * Translate the incoming request, which has an access token
20 | * Spring security takes the incoming request and injects the Java Security Principal
21 | * The converter inside Spring Security will handle the to json method which the Spring Security
22 | * Oauth client will know how to read
23 | *
24 | * The @EnableResourceServer on the application entry point is what makes all this magic happen.
25 | * If there is an incoming request token it will check the token validity and handle it accordingly
26 | */
27 | return principal;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/dazito/oauthexample/service/AccountUserDetailsService.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample.service;
2 |
3 | import com.dazito.oauthexample.repository.AccountRepository;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.security.core.authority.AuthorityUtils;
6 | import org.springframework.security.core.userdetails.User;
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 | /**
13 | * Created by daz on 29/06/2017.
14 | */
15 | @Service
16 | public class AccountUserDetailsService implements UserDetailsService {
17 |
18 | private AccountRepository accountRepository;
19 |
20 | @Autowired
21 | public AccountUserDetailsService(AccountRepository accountRepository) {
22 | this.accountRepository = accountRepository;
23 | }
24 |
25 | @Override
26 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
27 | return accountRepository
28 | .findByUsername(username)
29 | .map(account -> new User(account.getUsername(), account.getPassword(), AuthorityUtils.createAuthorityList("ROLE_USER")))
30 | .orElseThrow(() -> new UsernameNotFoundException("Could not find " + username));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8181
2 |
3 | # ===============================
4 | # = DATA SOURCE
5 | # ===============================
6 |
7 | # Set here configurations for the database connection
8 |
9 | # Connection url for the database w/createDatabaseIfNotExist=true
10 | spring.datasource.url = jdbc:mysql://localhost:3306/oauth_example?createDatabaseIfNotExist=true
11 | spring.database.driverClassName = com.mysql.jdbc.Driver
12 | spring.jpa.database = MySQL
13 | spring.datasource.platform = mysql
14 |
15 | # Database - data initialization
16 | spring.jpa.generate-ddl = true
17 |
18 | # Username and password
19 | spring.datasource.username = root
20 | spring.datasource.password = admin
21 |
22 | # ===============================
23 | # = JPA / HIBERNATE
24 | # ===============================
25 |
26 | # Use spring.jpa.properties.* for Hibernate native properties (the prefix is
27 | # stripped before adding them to the entity manager).
28 |
29 | # Show or not log for each sql query
30 | spring.jpa.show-sql = true
31 |
32 | # Transactions
33 | spring.jpa.open-in-view = false
34 |
35 | # Hibernate ddl auto (create, create-drop, update): with "update" the database
36 | # schema will be automatically updated accordingly to java entities found in
37 | # the project
38 | spring.jpa.hibernate.ddl-auto = update
39 |
40 | # Naming strategy
41 | spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
42 |
43 | # spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
44 | # Allows Hibernate to generate SQL optimized for a particular DBMS
45 | spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
--------------------------------------------------------------------------------
/src/main/resources/data.sql:
--------------------------------------------------------------------------------
1 | /** Oauth - populate the oauth_client_details table */
2 | INSERT INTO `oauth_client_details` (`client_id`, `client_secret`, `scope`, `authorized_grant_types`, `access_token_validity`, `additional_information`)
3 | VALUES
4 | ('web', 'secret', 'read', 'authorization_code,password,refresh_token,implicit', '900', '{}')
5 | ON DUPLICATE key UPDATE
6 | client_secret = VALUES(`client_secret`),
7 | scope = VALUES(`scope`),
8 | authorized_grant_types = VALUES(`authorized_grant_types`),
9 | access_token_validity = VALUES(`access_token_validity`),
10 | additional_information = VALUES(`additional_information`);
11 |
12 | INSERT INTO `oauth_example`.`account` (`id`, `password`, `username`) VALUES (' 1 ', 'dazito.com', 'dazito')
13 | ON DUPLICATE key UPDATE
14 | password = VALUES(`password`),
15 | username = VALUES(`username`);
16 |
--------------------------------------------------------------------------------
/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | create table if not exists oauth_client_details (
2 | client_id VARCHAR(255) PRIMARY KEY,
3 | resource_ids VARCHAR(255),
4 | client_secret VARCHAR(255),
5 | scope VARCHAR(255),
6 | authorized_grant_types VARCHAR(255),
7 | web_server_redirect_uri VARCHAR(255),
8 | authorities VARCHAR(255),
9 | access_token_validity INTEGER,
10 | refresh_token_validity INTEGER,
11 | additional_information VARCHAR(4096),
12 | autoapprove VARCHAR(255)
13 | );
14 |
15 | create table if not exists oauth_client_token (
16 | token_id VARCHAR(255),
17 | token LONG VARBINARY,
18 | authentication_id VARCHAR(255) PRIMARY KEY,
19 | user_name VARCHAR(255),
20 | client_id VARCHAR(255)
21 | );
22 |
23 | create table if not exists oauth_access_token (
24 | token_id VARCHAR(255),
25 | token LONG VARBINARY,
26 | authentication_id VARCHAR(255) PRIMARY KEY,
27 | user_name VARCHAR(255),
28 | client_id VARCHAR(255),
29 | authentication LONG VARBINARY,
30 | refresh_token VARCHAR(255)
31 | );
32 |
33 | create table if not exists oauth_refresh_token (
34 | token_id VARCHAR(255),
35 | token LONG VARBINARY,
36 | authentication LONG VARBINARY
37 | );
38 |
39 | create table if not exists oauth_code (
40 | code VARCHAR(255), authentication LONG VARBINARY
41 | );
42 |
43 | create table if not exists oauth_approvals (
44 | userId VARCHAR(255),
45 | clientId VARCHAR(255),
46 | scope VARCHAR(255),
47 | status VARCHAR(10),
48 | expiresAt TIMESTAMP,
49 | lastModifiedAt TIMESTAMP
50 | );
51 |
52 | create table if not exists ClientDetails (
53 | appId VARCHAR(255) PRIMARY KEY,
54 | resourceIds VARCHAR(255),
55 | appSecret VARCHAR(255),
56 | scope VARCHAR(255),
57 | grantTypes VARCHAR(255),
58 | redirectUrl VARCHAR(255),
59 | authorities VARCHAR(255),
60 | access_token_validity INTEGER,
61 | refresh_token_validity INTEGER,
62 | additionalInformation VARCHAR(4096),
63 | autoApproveScopes VARCHAR(255)
64 | );
--------------------------------------------------------------------------------
/src/test/java/com/dazito/oauthexample/OauthExampleApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.dazito.oauthexample;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class OauthExampleApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------