在以前的系列文章认证鉴权与API权限控制在微服务架构中的设计与实现中,咱们有四篇文章讲解了微服务下的认证鉴权与API权限控制的实现。当时基于的Spring Cloud版本为Dalston.SR4
,当前最新的Spring Cloud版本为Finchley.SR1
,对应的Spring Boot也升级到了2.0.x
。Spring Cloud版本为Finchley
和Spring Boot2.0相对以前的版本有较大的变化,至于具体的changes,请参见官网。本次会将项目升级到最新版本,下面具体介绍其中的变化。与使用以前的版本,请切换到1.0-RELEASE
。java
将Spring Boot的依赖升级为2.0.4.RELEASE
。mysql
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
</parent>
复制代码
升级dependencyManagement中的spring-cloud依赖为Finchley.RELEASE
。git
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
复制代码
删除spring-cloud-starter-oauth2
依赖,只留下spring-cloud-starter-security
依赖。github
咱们在项目中,引入了flyway的依赖,用以初始化数据库的增量脚本,具体能够参见数据库版本管理工具Flyway应用。redis
为了更加简便的体验本项目,笔者在项目中提供了docker compose脚本。在本地安装好docker compose的状况下,进入项目根目录执行docker-compose up
命令。算法
便可启动咱们所须要的mysql和redis。spring
在Spring Boot 2.0.X版本中,选择了HikariCP做为默认数据库链接池。因此咱们并不须要额外配置DataSource。sql
Mybatis的mapper和config-location配置也经过配置文件的形式,所以DatasourceConfig
大大简化。docker
spring:
flyway:
baseline-on-migrate: true
locations: classpath:db
datasource:
hikari:
connection-test-query: SELECT 1
minimum-idle: 1
maximum-pool-size: 5
pool-name: dbcp1
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/auth?autoReconnect=true&useSSL=false
username: ${AUTH_DB_PWD:root}
password: ${AUTH_DB_USER:_123456_}
# schema[0]: classpath:/auth.sql
# initialization-mode: ALWAYS
type: com.zaxxer.hikari.HikariDataSource
redis:
database: 0
host: localhost
port: 6379
mybatis:
mapper-locations: classpath:/mybatis/mapper/*Mapper.xml
config-location: classpath:/mybatis/config.xml
复制代码
弃用,因为循环依赖的问题,将AuthenticationManager
的配置放置到WebSecurityConfig
中。数据库
添加了来自AuthenticationManagerConfig
的AuthenticationManager
配置。
因为Spring Security5默认PasswordEncoder
不是NoOpPasswordEncoder
,须要手动指定。原来的auth项目中没有对密码进行加密,NoOpPasswordEncoder
已经被废弃,只适合在测试环境中使用,本次咱们使用SCryptPasswordEncoder
密码加密器对密码进行加解密,更贴近产线的使用。其余的算法还有Pbkdf2PasswordEncoder
和BCryptPasswordEncoder
。
关于Scrpyt算法,能够确定的是其很难被攻击。
Scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了下降CPU负荷,尽可能少的依赖cpu计算,利用CPU闲置时间进行计算,所以scrypt不只计算所需时间长,并且占用的内存也多,使得并行计算多个摘要异常困难,所以利用rainbow table进行暴力攻击更加困难。Scrpyt没有在生产环境中大规模应用,而且缺少仔细的审察和普遍的函数库支持。因此Scrpyt一直没有推广开,可是因为其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。
而BCrypt相对出现的时间更久,也很安全。Spring Security中的BCryptPasswordEncoder
方法采用SHA-256 + 随机盐 + 密钥对密码进行加密。SHA系列是Hash算法,不是加密算法,使用加密算法意味着能够解密(这个与编码/解码同样),可是采用Hash处理,其过程是不可逆的。
关于怎么初始化密码呢,和注册用户的时候怎么给密码加密,咱们能够在初始化密码时调用以下的方法:
SCryptPasswordEncoder sCryptPasswordEncoder = new SCryptPasswordEncoder();
sCryptPasswordEncoder.encode("frontend");
复制代码
此时须要对数据库中的client_secret
进行修改,如把frontend
修改成:
$e0801$65x9sjjnRPuKmqaFn3mICtPYnSWrjE7OB/pKzKTAI4ryhmVoa04cus+9sJcSAFKXZaJ8lcPO1I9H22TZk6EN4A==$o+ZWccaWXSA2t7TxE5VBRvz2W8psujU3RPPvejvNs4U=
复制代码
并修改配置以下:
@Autowired
CustomAuthenticationProvider customAuthenticationProvider;
@Autowired
CodeAuthenticationProvider codeAuthenticationProvider;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
auth.authenticationProvider(codeAuthenticationProvider);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new SCryptPasswordEncoder();
}
复制代码
弃用,auth项目不启用资源服务器的功能。
因为当前版本的spring-boot-redis
中的RedisConnection
缺乏#set
方法,直接使用RedisTokenStore
会出现如下异常:
java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.set([B[B)V
复制代码
所以自定义CustomRedisTokenStore
类,与RedisTokenStore代码一致,只是将RedisConnection#set
方法的调用替换为RedisConnection#stringCommands#set
,以下所示:
conn.stringCommands().set(accessKey, serializedAccessToken);
conn.stringCommands().set(authKey, serializedAuth);
conn.stringCommands().set(authToAccessKey, serializedAccessToken);
复制代码
完整代码见文末的GitHub地址。
通过如上的升级改造,咱们将验证以下的API端点:
结果就不展现了,均可以正常使用。
OAuth鉴权服务是微服务架构中的一个基础服务,项目公开以后获得了好多同窗的关注,好多同窗在加入QQ群以后也提出了本身关于这方面的疑惑或者建议,一块儿讨论和解决疑惑的地方。随着Spring Boot和Spring Cloud的版本升级,笔者也及时更新了本项目,但愿可以帮到一些童鞋。笔者筹划的一本关于Spring Cloud应用的书籍,本月即将出版面世,其中关于Spring Cloud Security部分,有着详细的解析,各位同窗能够支持一下正版。
本文的源码地址:
GitHub:github.com/keets2012/A…
码云: gitee.com/keets/Auth-…