├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── docker-compose.yml
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── blueskykong
│ │ └── auth
│ │ ├── AuthApplication.java
│ │ ├── config
│ │ ├── JerseyConfig.java
│ │ ├── ServiceConfig.java
│ │ └── oauth
│ │ │ ├── OAuth2Config.java
│ │ │ ├── ResourceServerConfig.java
│ │ │ └── WebSecurityConfig.java
│ │ ├── dao
│ │ ├── ClientSecretDAO.java
│ │ ├── PermissionDAO.java
│ │ ├── RoleDAO.java
│ │ ├── RolePermissionDAO.java
│ │ ├── UserAccessDAO.java
│ │ ├── UserRoleDAO.java
│ │ ├── impl
│ │ │ ├── MybatisClientSecretDAO.java
│ │ │ ├── MybatisPermissionDAO.java
│ │ │ ├── MybatisRoleDAO.java
│ │ │ ├── MybatisRolePermissionDAO.java
│ │ │ ├── MybatisURoleDAO.java
│ │ │ └── MybatisUserAccessDAO.java
│ │ ├── mapper
│ │ │ ├── ClientSecretMapper.java
│ │ │ ├── PermissionMapper.java
│ │ │ ├── RoleMapper.java
│ │ │ ├── RolePermissionMapper.java
│ │ │ ├── UserAccessMapper.java
│ │ │ └── UserRoleMapper.java
│ │ └── typehandler
│ │ │ └── UuidTypeHandler.java
│ │ ├── dto
│ │ ├── ApiClientDTO.java
│ │ ├── DefaultRole.java
│ │ ├── DefaultRoles.java
│ │ ├── RolePermissionDTO.java
│ │ └── UserRoleDTO.java
│ │ ├── entity
│ │ ├── BaseEntity.java
│ │ ├── ClientSecret.java
│ │ ├── ClientSecretStatus.java
│ │ ├── Permission.java
│ │ ├── Role.java
│ │ ├── RolePermission.java
│ │ ├── UserAccess.java
│ │ └── UserRole.java
│ │ ├── exception
│ │ ├── AbstractException.java
│ │ ├── CustomWebResponseExceptionTranslator.java
│ │ ├── ErrorCode.java
│ │ ├── ErrorCodes.java
│ │ └── GenericErrorCodes.java
│ │ ├── properties
│ │ └── RedisProperties.java
│ │ ├── rest
│ │ ├── ClientSecretResource.java
│ │ ├── SecurityResource.java
│ │ └── UserRoleResource.java
│ │ ├── security
│ │ ├── CodeAuthenticationProvider.java
│ │ ├── CustomAuthenticationProvider.java
│ │ ├── CustomAuthenticationToken.java
│ │ ├── CustomAuthorizationTokenServices.java
│ │ ├── CustomCheckPermission.java
│ │ ├── CustomRedisTokenStore.java
│ │ ├── CustomTokenEnhancer.java
│ │ ├── CustomUserDetails.java
│ │ └── filter
│ │ │ ├── CustomLogoutHandler.java
│ │ │ ├── CustomSecurityFilter.java
│ │ │ ├── SecureResourceFilterInvocationDefinitionSource.java
│ │ │ └── SecurityAccessDecisionManager.java
│ │ ├── service
│ │ ├── ClientSecretService.java
│ │ └── SecurityService.java
│ │ └── utils
│ │ ├── JsonUtil.java
│ │ └── TimestampAdapter.java
└── resources
│ ├── application.yml
│ ├── bootstrap.yml
│ ├── conf
│ └── generatorConfig.xml
│ ├── db
│ └── V1.0__Base_version.sql
│ └── mybatis
│ ├── config.xml
│ └── mapper
│ ├── ClientSecretMapper.xml
│ ├── PermissionMapper.xml
│ ├── RoleMapper.xml
│ ├── RolePermissionMapper.xml
│ ├── UserAccessMapper.xml
│ └── UserRoleMapper.xml
└── test
├── java
└── com
│ └── blueskykong
│ └── auth
│ ├── AuthApplicationTest.java
│ └── config
│ ├── BaseServiceTest.java
│ ├── CustomContextInitializer.java
│ └── TestJdbcConfig.java
└── resources
└── application-test.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Config Files
4 | .classpath
5 | *.MF
6 | *.project
7 | .settings
8 | .tern-project
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 |
18 | checkstyle/
19 | target/
20 | *.iml
21 | auditlog/
22 | .idea/
23 | .DS_Store
24 | tmp.*
25 |
26 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
27 | hs_err_pid*
28 | /src/main/resources/*.yml
29 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - openjdk8
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 aoho
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/keets2012/Auth-service)
2 | [](https://codebeat.co/projects/github-com-keets2012-auth-service-master)
3 | 
4 |
5 | ## change logs
6 |
7 | - 2018.9.1
8 |
9 | 版本升到`2.0-SNAPSHOT`,欲使用`sb1.5.x`版本,请切换到TAG `1.0-RELEASE`。by [CANGWU](https://github.com/CANGWU)
10 |
11 | Spring Cloud Security 升级到`Finchley.RELEASE`,Spring Boot由1.5.X升级到2.0.X。
12 |
13 | ```xml
14 |
15 | org.springframework.cloud
16 | spring-cloud-dependencies
17 | Finchley.RELEASE
18 |
19 | ```
20 |
21 | ```xml
22 |
23 | org.springframework.boot
24 | spring-boot-starter-parent
25 | 2.0.0.RELEASE
26 |
27 | ```
28 |
29 | ## quick start
30 | 本次对项目结构进行了更新,token的存储机制基于redis,当然存储方式可以自由切换,Spring Security提供了SPI的多种实现。
31 |
32 | 客户端的信息还是基于jdbc实现,所以需要导入项目中提供的表`oauth_client_details` 。
33 |
34 | 推荐首先阅读专栏文章:[认证鉴权与API权限控制在微服务架构中的设计与实现](http://blueskykong.com/categories/Security/)
35 |
36 | **单独的整合项目地址为:
37 | GitHub:https://github.com/keets2012/microservice-integration
38 | 或者 码云:https://gitee.com/keets/microservice-integration**
39 |
40 | ### maintainer
41 | - keets2012
42 | - CANGWU
43 |
44 | ### password模式
45 | 项目克隆之后:
46 |
47 | 1. ~~安装一下,`mvn clean install`~~
48 | 2. 修改Auth项目中的配置文件,写了`XXXX`的地方,替换成自己的实际地址(redis和mysql)
49 | 3. 数据库导入,sql脚本在项目中。创建auth数据库,运行auth.sql
50 | 4. `mvn clean spring-boot:run`
51 | 5. 其他细节参考博客
52 | 6. **你的star是对我最好的鼓励^_^**
53 |
54 | 进行请求获取Token授权:
55 | 
56 | 
57 |
58 |
59 | 笔者自己运行了结果如下:
60 |
61 | ```yaml
62 | {
63 | "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDkwNzMzMjcsIlgtQU9ITy1Vc2VySWQiOiIxNGY1MmE0OS0yYTgxLTRhMmYtOGI5Mi01ZmU0NzUzZGRmZGEiLCJ1c2VyX25hbWUiOiIxODM2MjkxNjcyNiIsImp0aSI6IjM5NDEzN2I5LTNjZGItNGUyNy04NGRjLWM5YjEyYzk3ZTA4YyIsImNsaWVudF9pZCI6ImZyb250ZW5kIiwic2NvcGUiOlsiYWxsIl19.pGZhGNVECg0b4LB_pYXTTVKjNn8FA5biM04Bhcd-MEE",
64 | "token_type": "bearer",
65 | "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiIxODM2MjkxNjcyNiIsInNjb3BlIjpbImFsbCJdLCJhdGkiOiIzOTQxMzdiOS0zY2RiLTRlMjctODRkYy1jOWIxMmM5N2UwOGMiLCJleHAiOjE1MTE2MjIxMjcsIlgtQU9ITy1Vc2VySWQiOiIxNGY1MmE0OS0yYTgxLTRhMmYtOGI5Mi01ZmU0NzUzZGRmZGEiLCJqdGkiOiJkYTBmOTMxMS1lZjc0LTRiMjQtODViZi04ZTNjNDVhNGEyNzkiLCJjbGllbnRfaWQiOiJmcm9udGVuZCJ9.2MRdqEogAwbesRfj2TKoWhMazItBlpjbQx7dlgfFpHE",
66 | "expires_in": 43199,
67 | "scope": "all",
68 | "X-AOHO-UserId": "14f52a49-2a81-4a2f-8b92-5fe4753ddfda",
69 | "jti": "394137b9-3cdb-4e27-84dc-c9b12c97e08c",
70 | "X-AOHO-ClientId": "frontend"
71 | }
72 | ```
73 |
74 | ps: 登录的用户名密码要在表单里面写,内容随意,因为在代码中已经去掉了对user服务的校验。
75 |
76 | ### 授权码模式
77 | 本次更新添加了对授权码模式的使用
78 |
79 | 授权码模式需要用户登录,所以借助浏览器
80 |
81 | 首先给数据库表中的`oauth_client_details`表中`client_id`为`frontend`的行`authorized_grant_types`添加`authorization_code`,`web_server_redirect_uri`设置为`http://localhost:8080`。表示该客户端允许授权码模式以及授权码回调地址为http://localhost:8080
82 |
83 | 浏览器访问地址
84 |
85 | ```yaml
86 | http://localhost:9000/oauth/authorize?response_type=code&client_id=frontend&
87 | scope=all&redirect_uri=http://localhost:8080
88 | ```
89 |
90 |
91 | 进入登录授权页面并同意授权,从回调地址中获取授权码
92 |
93 | ```yaml
94 | http://localhost:8080/?code=xGjrTm
95 | ```
96 |
97 | 通过授权码获取access_token
98 |
99 | ```yaml
100 | method: post
101 | url: http://localhost:9000/oauth/token?grant_type=authorization_code
102 | header:
103 | {
104 | Authorization: Basic ZnJvbnRlbmQ6ZnJvbnRlbmQ=,
105 | Content-Type: application/x-www-form-urlencoded
106 | }
107 | body:
108 | {
109 | code: xGjrTm,
110 | redirect_uri: http://localhost:8080
111 | }
112 | ```
113 |
114 | ### 写在最后
115 |
116 | 项目整合如果遇到问题,可以加入qq群(649932629)交流。
117 |
118 | 
119 |
120 | ps: qq交流群已设置付费,可以过滤很多广告,营造高质量的技术交流群。
121 |
122 | *有问题联系 aoho002#gmail.com*
123 |
124 | ### MIT License
125 |
126 | Copyright (c) 2018 aoho
127 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | mysql-auth:
2 | restart: always
3 | image: mysql:5.7
4 | ports:
5 | - "3306:3306"
6 | environment:
7 | - MYSQL_ROOT_PASSWORD=_123456_
8 | - MYSQL_DATABASE=auth
9 |
10 | redis:
11 | container_name: auth-redis
12 | image: 'redis:4'
13 | ports:
14 | - '6379:6379'
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | Auth-Service
8 | com.blueskykong
9 | 2.0-SNAPSHOT
10 | jar
11 |
12 | OAuth Service
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.4.RELEASE
18 |
19 |
20 |
21 | UTF-8
22 | UTF-8
23 | 1.8
24 | false
25 | 1.3.0
26 | 2.5.3
27 | 2.2.0
28 | 1.85
29 |
30 |
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-data-redis
35 |
36 |
37 |
38 | org.mybatis.spring.boot
39 | mybatis-spring-boot-starter
40 | ${mybatis.spring.version}
41 |
42 |
43 |
44 | org.projectlombok
45 | lombok
46 | provided
47 |
48 |
49 |
50 | org.springframework.cloud
51 | spring-cloud-starter-netflix-hystrix
52 |
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-starter-actuator
57 |
58 |
59 |
60 | com.auth0
61 | java-jwt
62 | ${jwt.version}
63 |
64 |
65 | org.springframework.cloud
66 | spring-cloud-starter-security
67 |
68 |
69 | org.springframework.cloud
70 | spring-cloud-security
71 |
72 |
73 | org.springframework.boot
74 | spring-boot-starter-web
75 |
76 |
77 |
78 | org.springframework.boot
79 | spring-boot-starter-jersey
80 |
81 |
82 |
83 |
84 | mysql
85 | mysql-connector-java
86 |
87 |
88 |
89 | org.springframework.boot
90 | spring-boot-starter-jdbc
91 |
92 |
93 |
94 | org.springframework.boot
95 | spring-boot-starter-test
96 | test
97 |
98 |
99 |
100 | org.springframework
101 | spring-aspects
102 | compile
103 |
104 |
105 |
106 | org.dbunit
107 | dbunit
108 | ${dbunit.version}
109 | test
110 |
111 |
112 |
113 | org.flywaydb
114 | flyway-core
115 |
116 |
117 |
118 | org.apache.commons
119 | commons-lang3
120 | 3.5
121 |
122 |
123 | net.sf.oval
124 | oval
125 | ${oval.version}
126 |
127 |
128 |
129 | io.jsonwebtoken
130 | jjwt
131 | 0.6.0
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | org.springframework.cloud
140 | spring-cloud-dependencies
141 | Finchley.RELEASE
142 | pom
143 | import
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | org.springframework.boot
153 | spring-boot-maven-plugin
154 |
155 |
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/src/main/java/com/blueskykong/auth/AuthApplication.java:
--------------------------------------------------------------------------------
1 | package com.blueskykong.auth;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class AuthApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(AuthApplication.class, args);
11 | }
12 |
13 | }
--------------------------------------------------------------------------------
/src/main/java/com/blueskykong/auth/config/JerseyConfig.java:
--------------------------------------------------------------------------------
1 | package com.blueskykong.auth.config;
2 |
3 |
4 | import com.blueskykong.auth.rest.ClientSecretResource;
5 | import com.blueskykong.auth.rest.SecurityResource;
6 | import com.blueskykong.auth.rest.UserRoleResource;
7 | import org.glassfish.jersey.server.ResourceConfig;
8 | import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
9 | import org.springframework.stereotype.Component;
10 |
11 | import javax.ws.rs.ApplicationPath;
12 |
13 |
14 | @Component
15 | @ApplicationPath("api")
16 | public class JerseyConfig extends ResourceConfig {
17 | public JerseyConfig() {
18 | register(RequestContextFilter.class);
19 | register(ClientSecretResource.class);
20 | //配置restful package.
21 | register(SecurityResource.class);
22 | register(UserRoleResource.class);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/com/blueskykong/auth/config/ServiceConfig.java:
--------------------------------------------------------------------------------
1 | package com.blueskykong.auth.config;
2 |
3 | import com.blueskykong.auth.exception.CustomWebResponseExceptionTranslator;
4 | import org.mybatis.spring.annotation.MapperScan;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
8 |
9 |
10 | @Configuration
11 | public class ServiceConfig {
12 |
13 | @Bean
14 | public WebResponseExceptionTranslator webResponseExceptionTranslator() {
15 | return new CustomWebResponseExceptionTranslator();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/blueskykong/auth/config/oauth/OAuth2Config.java:
--------------------------------------------------------------------------------
1 | package com.blueskykong.auth.config.oauth;
2 |
3 | import com.blueskykong.auth.security.CustomAuthorizationTokenServices;
4 | import com.blueskykong.auth.security.CustomRedisTokenStore;
5 | import com.blueskykong.auth.security.CustomTokenEnhancer;
6 | import com.blueskykong.auth.service.ClientSecretService;
7 | import com.zaxxer.hikari.HikariDataSource;
8 | import org.mybatis.spring.annotation.MapperScan;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
11 | import org.springframework.context.annotation.AdviceMode;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.annotation.Configuration;
14 | import org.springframework.context.annotation.Lazy;
15 | import org.springframework.core.annotation.Order;
16 | import org.springframework.data.redis.connection.RedisConnectionFactory;
17 | import org.springframework.data.redis.core.RedisTemplate;
18 | import org.springframework.data.redis.core.StringRedisTemplate;
19 | import org.springframework.security.authentication.AuthenticationManager;
20 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
21 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
22 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
23 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
24 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
25 | import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
26 | import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
27 | import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
28 | import org.springframework.security.oauth2.provider.token.TokenStore;
29 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
30 | import org.springframework.transaction.annotation.EnableTransactionManagement;
31 |
32 | import javax.sql.DataSource;
33 | import java.net.UnknownHostException;
34 |
35 | @Configuration
36 | @EnableAuthorizationServer
37 | public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
38 |
39 |
40 | private AuthenticationManager authenticationManager;
41 |
42 | private WebResponseExceptionTranslator webResponseExceptionTranslator;
43 |
44 | private DataSource dataSource;
45 |
46 | private RedisConnectionFactory redisConnectionFactory;
47 |
48 | @Autowired
49 | public OAuth2Config(AuthenticationManager authenticationManager, WebResponseExceptionTranslator webResponseExceptionTranslator,
50 | HikariDataSource dataSource, RedisConnectionFactory redisConnectionFactory) {
51 | this.authenticationManager = authenticationManager;
52 | this.webResponseExceptionTranslator = webResponseExceptionTranslator;
53 | this.dataSource = dataSource;
54 | this.redisConnectionFactory = redisConnectionFactory;
55 | }
56 |
57 | @Bean
58 | public TokenStore tokenStore(RedisConnectionFactory redisConnectionFactory) {
59 | return new CustomRedisTokenStore(redisConnectionFactory);
60 | }
61 |
62 | @Bean
63 | public JdbcClientDetailsService clientDetailsService() {
64 | return new JdbcClientDetailsService(dataSource);
65 | }
66 |
67 | @Override
68 | public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
69 | //security.addTokenEndpointAuthenticationFilter(new CustomSecurityFilter());
70 | security
71 | .tokenKeyAccess("permitAll()")
72 | .checkTokenAccess("isAuthenticated()");
73 | }
74 |
75 | @Override
76 | public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
77 | clients.withClientDetails(clientDetailsService());
78 | }
79 |
80 | @Override
81 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
82 | endpoints.authenticationManager(authenticationManager)
83 | .tokenStore(tokenStore(redisConnectionFactory))
84 | .tokenServices(authorizationServerTokenServices())
85 | .accessTokenConverter(accessTokenConverter())
86 | .exceptionTranslator(webResponseExceptionTranslator);
87 | }
88 |
89 | @Bean
90 | public JwtAccessTokenConverter accessTokenConverter() {
91 | JwtAccessTokenConverter converter = new CustomTokenEnhancer();
92 | converter.setSigningKey("secret");
93 | return converter;
94 | }
95 |
96 | @Bean
97 | public AuthorizationServerTokenServices authorizationServerTokenServices() {
98 | CustomAuthorizationTokenServices customTokenServices = new CustomAuthorizationTokenServices();
99 | customTokenServices.setTokenStore(tokenStore(redisConnectionFactory));
100 | customTokenServices.setSupportRefreshToken(true);
101 | customTokenServices.setReuseRefreshToken(false);
102 | customTokenServices.setClientDetailsService(clientDetailsService());
103 | customTokenServices.setTokenEnhancer(accessTokenConverter());
104 | return customTokenServices;
105 | }
106 |
107 | @Configuration
108 | protected static class RedisConfiguration {
109 |
110 | @Bean
111 | @ConditionalOnMissingBean(name = "redisTemplate")
112 | public RedisTemplate