1. 环境说明
无网络隔离是指用户访问的网络环境与整个系统的部署网络环境是相通的,例如用户可以绕过API网关直接访问后台的服务。
2. 架构与设计思路
2.1 架构图
2.2 设计思路
2.2.1 统一认证
- 负责登录认证
token
派发token
刷新- 应用接入管理
- …
2.2.2 API网关
只负责路由转发
2.2.3 微服务
每个服务都需加入认证中心的sdk
负责所有请求的鉴权
2.2.4 TokenResolver
嵌入在微服务程序中通过SecurityContextHolder
获取当前登录人,主要原理如下:
- 判断当前
url
请求的方法有没有带有@LoginUser
注解 - 判断
@LoginUser
注解的isFull属性是否为true
则通过username
查询用户对象 - 构建
SysUser
对象传给目标方法
3. 优化
与前面的架构对比,下图改进保证每个服务的API
都有认证,并且客户端与服务内部分别使用不同的token
同时融合了redisToken
和jwt
两者的优点,架构图如下:
3.1 设计思路
3.1.1 客户端使用redisToken
- 减少网络带宽消耗:普通的
uuid token
对于jwt
的长度小很多 - 能实现更多的功能:使用
redisToken
功能更多,能方便实现如token
自动续约、在线用户列表、踢人等功能
3.1.2 内部服务使用jwt
- 场景符合:由于是内部服务使用,客户端只能获取
access token
没有jwt
,所以无需让jwt token
失效符合jwt
特性 - 提升性能:服务与服务之间的通信只需通过
jwt
自解析认证,无需网络连接,大大减少redis
的压力和提升性能 - 增加安全性:内部服务与客户端所使用的
token
不一样,能有效防止客户端绕开网关直接请求后面服务
4. 实践思路
- 自己实现一个
RedisTokenStore
在storeAccessToken
的时候使用私钥生成JWT
并存到Redis
中 - 网关添加过滤器在认证
access_token
成功后,获取JWT
存到header
中请求后面的内部服务 - 每个内部服务都添加
@EnableResourceServer
配置为资源服务器,并且ylw.oauth2.token.store
设置为resJwt
使用公钥自解析JWT