前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >认证鉴权与API权限控制在微服务架构中的设计与实现:升级

认证鉴权与API权限控制在微服务架构中的设计与实现:升级

作者头像
aoho求索
发布2018-10-09 15:49:59
9550
发布2018-10-09 15:49:59
举报
文章被收录于专栏:aoho求索aoho求索

概述

在之前的系列文章认证鉴权与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

升级依赖

将Spring Boot的依赖升级为2.0.4.RELEASE

代码语言:javascript
复制
1<parent>
2    <groupId>org.springframework.boot</groupId>
3    <artifactId>spring-boot-starter-parent</artifactId>
4    <version>2.0.4.RELEASE</version>
5</parent>

升级dependencyManagement中的spring-cloud依赖为Finchley.RELEASE

代码语言:javascript
复制
 1<dependencyManagement>
 2     <dependencies>
 3         <dependency>
 4             <groupId>org.springframework.cloud</groupId>
 5             <artifactId>spring-cloud-dependencies</artifactId>
 6             <version>Finchley.RELEASE</version>
 7             <type>pom</type>
 8             <scope>import</scope>
 9         </dependency>
10     </dependencies>
11</dependencyManagement>

删除spring-cloud-starter-oauth2依赖,只留下spring-cloud-starter-security依赖。

工具升级

flyway

我们在项目中,引入了flyway的依赖,用以初始化数据库的增量脚本,具体可以参见数据库版本管理工具Flyway应用。

docker容器

为了更加简便的体验本项目,笔者在项目中提供了docker compose脚本。在本地安装好docker compose的情况下,进入项目根目录执行docker-compose up命令。

即可启动我们所需要的mysql和redis。

Mybatis和HikariCP

在Spring Boot 2.0.X版本中,选择了HikariCP作为默认数据库连接池。所以我们并不需要额外配置DataSource。

Mybatis的mapper和config-location配置也通过配置文件的形式,因此DatasourceConfig大大简化。

application.yml

代码语言:javascript
复制
 1spring:
 2  flyway:
 3    baseline-on-migrate: true
 4    locations: classpath:db
 5  datasource:
 6    hikari:
 7      connection-test-query: SELECT 1
 8      minimum-idle: 1
 9      maximum-pool-size: 5
10      pool-name: dbcp1
11    driver-class-name: com.mysql.jdbc.Driver
12    url: jdbc:mysql://localhost:3306/auth?autoReconnect=true&useSSL=false
13    username: ${AUTH_DB_PWD:root}
14    password: ${AUTH_DB_USER:_123456_}
15#    schema[0]: classpath:/auth.sql
16#    initialization-mode: ALWAYS
17    type: com.zaxxer.hikari.HikariDataSource
18  redis:
19    database: 0
20    host: localhost
21    port: 6379
22
23mybatis:
24  mapper-locations: classpath:/mybatis/mapper/*Mapper.xml
25  config-location: classpath:/mybatis/config.xml

配置类升级

AuthenticationManagerConfig

弃用,由于循环依赖的问题,将AuthenticationManager的配置放置到WebSecurityConfig中。

WebSecurityConfig

添加了来自AuthenticationManagerConfigAuthenticationManager配置。

由于Spring Security5默认PasswordEncoder不是NoOpPasswordEncoder,需要手动指定。原来的auth项目中没有对密码进行加密,NoOpPasswordEncoder已经被废弃,只适合在测试环境中使用,本次我们使用SCryptPasswordEncoder密码加密器对密码进行加解密,更贴近产线的使用。其他的算法还有Pbkdf2PasswordEncoderBCryptPasswordEncoder

关于Scrpyt算法,可以肯定的是其很难被攻击。

Scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。Scrpyt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以Scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。

而BCrypt相对出现的时间更久,也很安全。Spring Security中的BCryptPasswordEncoder方法采用SHA-256 + 随机盐 + 密钥对密码进行加密。SHA系列是Hash算法,不是加密算法,使用加密算法意味着可以解密(这个与编码/解码一样),但是采用Hash处理,其过程是不可逆的。

  1. 加密(encode):注册用户时,使用SHA-256+随机盐+密钥把用户输入的密码进行hash处理,得到密码的hash值,然后将其存入数据库中。
  2. 密码匹配(matches):用户登录时,密码匹配阶段并没有进行密码解密(因为密码经过Hash处理,是不可逆的),而是使用相同的算法把用户输入的密码进行hash处理,得到密码的hash值,然后将其与从数据库中查询到的密码hash值进行比较。如果两者相同,说明用户输入的密码正确。

关于怎么初始化密码呢,和注册用户的时候怎么给密码加密,我们可以在初始化密码时调用如下的方法:

代码语言:javascript
复制
1SCryptPasswordEncoder sCryptPasswordEncoder = new SCryptPasswordEncoder();
2sCryptPasswordEncoder.encode("frontend");

此时需要对数据库中的client_secret进行修改,如把frontend修改为:

代码语言:javascript
复制
1$e0801$65x9sjjnRPuKmqaFn3mICtPYnSWrjE7OB/pKzKTAI4ryhmVoa04cus+9sJcSAFKXZaJ8lcPO1I9H22TZk6EN4A==$o+ZWccaWXSA2t7TxE5VBRvz2W8psujU3RPPvejvNs4U=

并修改配置如下:

代码语言:javascript
复制
 1    @Autowired
 2    CustomAuthenticationProvider customAuthenticationProvider;
 3    @Autowired
 4    CodeAuthenticationProvider codeAuthenticationProvider;
 5
 6    @Override
 7    public void configure(AuthenticationManagerBuilder auth) throws Exception {
 8        auth.authenticationProvider(customAuthenticationProvider);
 9        auth.authenticationProvider(codeAuthenticationProvider);
10    }
11
12    @Bean
13    @Override
14    public AuthenticationManager authenticationManagerBean() throws Exception {
15        return super.authenticationManagerBean();
16    }
17
18   @Bean
19    public PasswordEncoder passwordEncoder(){
20        return new SCryptPasswordEncoder();
21    }

ResourceServerConfig

弃用,auth项目不启用资源服务器的功能。

OAuth2Config

由于当前版本的spring-boot-redis中的RedisConnection缺少#set方法,直接使用RedisTokenStore会出现以下异常:

代码语言:javascript
复制
1java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.set([B[B)V

因此自定义CustomRedisTokenStore类,与RedisTokenStore代码一致,只是将RedisConnection#set方法的调用替换为RedisConnection#stringCommands#set,如下所示:

代码语言:javascript
复制
1    conn.stringCommands().set(accessKey, serializedAccessToken);
2    conn.stringCommands().set(authKey, serializedAuth);
3    conn.stringCommands().set(authToAccessKey, serializedAccessToken);

完整代码见文末的GitHub地址。

结果验证

经过如上的升级改造,我们将验证如下的API端点:

  • password模式获取token:/oauth/token?grant_type=password
  • 刷新token:/oauth/token?grant_type=refresh_token&refresh_token=…
  • 检验token:/oauth/check_token
  • 登出:/logout
  • 授权:/oauth/authorize
  • 授权码模式获取token:/oauth/token?grant_type=authorization_code

结果就不展示了,都可以正常使用。

小结

OAuth鉴权服务是微服务架构中的一个基础服务,项目公开之后得到了好多同学的关注,好多同学在加入QQ群之后也提出了自己关于这方面的疑惑或者建议,一起讨论和解决疑惑的地方。随着Spring Boot和Spring Cloud的版本升级,笔者也及时更新了本项目,希望能够帮到一些童鞋。笔者筹划的一本关于Spring Cloud应用的书籍,本月即将出版面世,其中关于Spring Cloud Security部分,有着详细的解析,各位同学可以支持一下正版。

本文的源码地址

GitHub:https://github.com/keets2012/Auth-service

码云: https://gitee.com/keets/Auth-Service

参考

scrypt算法的前世今生(从零开始学区块链 192)https://www.sohu.com/a/167016356_99901444

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 aoho求索 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 升级依赖
  • 工具升级
    • flyway
      • docker容器
        • Mybatis和HikariCP
          • application.yml
          • 配置类升级
            • AuthenticationManagerConfig
              • WebSecurityConfig
                • ResourceServerConfig
                  • OAuth2Config
                  • 结果验证
                  • 小结
                    • 参考
                    相关产品与服务
                    容器服务
                    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档