记得之前写过一篇文章微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权! ,提供了Spring Cloud中的权限解决方案,其实一开始整合的时候我一直玩不转,又是查资料又是看源码,最终才成功了。最近尝试了下Sa-Token提供的微服务权限解决方案,用起来感觉很优雅,推荐给大家!
SpringBoot实战电商项目mall(50k+star)地址:github.com/macrozheng/…
前置知识
我们将采用Nacos作为注册中心,Gateway作为网关,使用Sa-Token提供的微服务权限解决方案,此方案是基于之前的解决方案改造的,对这些技术不了解的朋友可以看下下面的文章。
- Spring Cloud Gateway:新一代API网关服务
- Spring Cloud Alibaba:Nacos 作为注册中心和配置中心使用
- 微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权!
- Sa-Token使用教程
应用架构
还是和之前方案差不多的思路,认证服务负责登录处理,网关负责登录认证和权限认证,其他API服务负责处理自己的业务逻辑。为了能在多个服务中共享Sa-Token的Session,所有服务都需要集成Sa-Token和Redis。
- micro-sa-token-common:通用工具包,其他服务公用的用户类
UserDTO
和通用返回结果类CommonResult
被抽取到了这里。 - micro-sa-token-gateway:网关服务,负责请求转发、登录认证和权限认证。
- micro-sa-token-auth:认证服务,仅包含一个登录接口,调用Sa-Token的API实现。
- micro-sa-token-api:受保护的API服务,用户通过网关鉴权通过后可以访问该服务。
方案实现
接下来实现下这套解决方案,依次搭建网关服务、认证服务和API服务。
micro-sa-token-gateway
我们首先来搭建下网关服务,它将负责整个微服务的登录认证和权限认证。
- 除了通用的Gateway依赖,我们还需要在
pom.xml
中添加如下依赖,包括Sa-Token的Reactor响应式依赖,整合Redis实现分布式Session的依赖以及我们的micro-sa-token-common
依赖;
1 | xml复制代码<dependencies> |
- 接下来修改配置文件
application.yml
,添加Redis配置和Sa-Token的配置,如果你看过之前那篇Sa-Token使用教程的话,基本就知道这些配置的作用了;
1 | yaml复制代码spring: |
- 添加Sa-Token的配置类
SaTokenConfig
,注入一个过滤器用于登录认证和权限认证,在setAuth
方法中添加路由规则,在setError
方法中添加鉴权失败的回调处理;
1 | java复制代码@Configuration |
- 扩展下Sa-Token提供的
StpInterface
接口,用于获取用户的权限,我们在用户登录以后会把用户信息存到Session中去,权限信息也会在里面,所以权限码只要从Session中获取即可。
1 | java复制代码/** |
micro-sa-token-auth
接下来我们来搭建下认证服务,只要集成Sa-Token并实现登录接口即可,非常简单。
- 首先在
pom.xml
中添加相关依赖,包括Sa-Token的SpringBoot依赖、整合Redis实现分布式Session的依赖以及我们的micro-sa-token-common
依赖;
1 | xml复制代码<dependencies> |
- 接下来修改配置文件
application.yml
,照抄之前网关的配置即可;
1 | yaml复制代码spring: |
- 在
UserController
中定义好登录接口,登录成功后返回Token,具体实现在UserServiceImpl
类中;
1 | java复制代码/** |
- 在
UserServiceImpl
中添加登录的具体逻辑,首先验证密码,密码校验成功后,通知下Sa-Token登录的用户ID,然后把用户信息直接存储到Session中去;
1 | java复制代码/** |
- 这里有一点需要提醒下,Sa-Token的Session并不是我们平时理解的HttpSession,而是它自己实现的类似Session的机制。
micro-sa-token-api
接下来我们来搭建一个受保护的API服务,实现获取登录用户信息的接口和需要特殊权限才能访问的测试接口。
- 首先在
pom.xml
中添加相关依赖,和上面的micro-sa-token-auth
一样;
1 | xml复制代码<dependencies> |
- 接下来修改配置文件
application.yml
,照抄之前网关的配置即可;
1 | yaml复制代码spring: |
- 添加获取用户信息的接口,由于使用了Redis实现分布式Session,直接从Session中获取即可,是不是非常简单!
1 | java复制代码/** |
- 添加需要
api:test:hello
权限访问的测试接口,预置的admin
用户拥有该权限,而macro
用户是没有的。
1 | java复制代码/** |
功能演示
三个服务搭建完成后,我们用Postman来演示下微服务的认证授权功能。
- 首先启动Nacos和Redis服务,然后再启动
micro-sa-token-gateway
、micro-sa-token-auth
和micro-sa-token-api
服务,启动顺序无所谓;
- 直接通过网关访问登录接口获取Token,访问地址:http://localhost:9201/auth/user/login
- 通过网关访问API服务,
不带Token
调用获取用户信息的接口,无法正常访问,访问地址:http://localhost:9201/api/user/info
- 通过网关访问API服务,
带Token
调用获取用户信息的接口,可以正常访问;
- 通过网关访问API服务,使用
macro
用户访问需api:test:hello
权限的测试接口,无法正常访问,访问地址:http://localhost:9201/api/test/hello
- 登录切换为
admin
用户,该用户具有api:test:hello
权限;
- 通过网关访问API服务,使用
admin
用户访问测试接口,可以正常访问。
总结
对比之前使用Spring Security的微服务权限解决方案,Sa-Token的解决方案更简单、更优雅。使用Security我们需要定义鉴权管理器、分别处理未认证和未授权的情况、还要自己定义认证和资源服务器配置,使用非常繁琐。而使用Sa-Token,只要在网关上配置过滤器实现认证和授权,然后调用API实现登录及权限分配即可。具体区别可以参考下图。
参考资料
官方文档:sa-token.dev33.cn/
项目源码地址
本文转载自: 掘金