鱼鱼
鱼鱼
发布于 2025-10-28 / 8 阅读
0
0

Spring Authorization Server鉴权流程

OAuth2鉴权流程

其实和认证相对的,还有鉴权流程,鉴权是需要资源服务器配合的,由于资源服务器是真正的业务服务,所以会有很多,所以资源服务器的配置是必须抽出来的。

我希望在微服务每个服务开发的过程中,只需要在自己的工程里引入依赖包,并做简单配置,即可作为资源服务器加入整个SAS的鉴权体系中来,所以资源服务器的配置部分写入公共包。

1.鉴权总流程

其实与AuthorizationServerConfiguration类似,资源服务器也有着掌管主要流程的配置类

ResourceServerConfiguration也是配置返回SecurityFilterChain来实现的

.oauth2ResourceServer(oauth2 -> oauth2
        .opaqueToken(token -> token.introspector(customOpaqueTokenIntrospector))
        .authenticationEntryPoint(resourceAuthExceptionEntryPoint)
        .bearerTokenResolver(dmsBearerTokenExtractor))

opaqueToken其实就是不透明令牌的处理,

Introspector指定了校验token的处理方式,

bearerTokenResolver是定义了如何从请求中获取token

其实简化一下流程就是

+-----------------+
|                 |
|   客户端应用     |
| (Web/移动端/API)|
+--------+--------+
         |
         | 1. 发送请求(携带Access Token)
         v
+-------------------------------+
|                               |
|   DmsBearerTokenExtractor     |
| (提取请求中的Bearer Token)    |
+---------------+---------------+
                |
                | 2. 提取出Access Token
                v
+-------------------------------+
|                               |
| OpaqueTokenIntrospector       |
| (自定义不透明令牌解析器)       |
|  - 校验Token有效性             |
|  - 解析用户信息和权限           |
+---------------+---------------+
                |
        +-------+-------+
        |               |
        v               v
   Token有效?          Token无效?
        |               |
        |               |
        v               v
+----------------+   +---------------------------+
|                |   |                           |
|  授权成功       |   |  ResourceAuthExceptionEntryPoint |
|  进入Controller |   | (返回401/403异常响应)       |
|  或方法级安全   |   |                           |
+--------+-------+   +---------------------------+
         |
         v
+----------------+
|                |
|   资源服务器    |
|  返回受保护资源 |
|   给客户端       |
+----------------+

其实这其中最重要的就是DmsCustomOpaqueTokenIntrospector这个类

1.它做了什么呢?验证令牌有效 + 获取关联信息 + 组装用户权限

接下来Introspector返回的用户和权限信息会写入每个请求(request)自己的 SecurityContext中。

2.它是怎么获取到的?认证过程中authorizationService会持久化token,我们选择的redis保存,所以在资源服务器中,可以调用authorizationService.findByToken,然后组装对象返回,然后由BearerTokenAuthenticationFilter(OAuth2框架标准方法)放入上下文;3.BearerTokenAuthenticationFilter它实际上控制了整个 token 校验和认证流程的调用顺序

2.注解引入

为了方便使用,参考了市面上比较流行的框架解决方案,注解鉴权和内部方法调用封装鉴权

HasPermission注解

它是基于 Spring Security 的 @PreAuthorize实现的,

例如@HasPermission("user:list,user:create")加在了controller接口方法上

Spring 会解析 @pms.hasPermission('user:list,user:create'.split(','))

拿到当前用户的 Authentication(从 SecurityContextHolder

调用 pms.hasPermission(String[] permissions) 方法判断是否有权限

Inner注解

带 @Inner 注解的方法/类,只允许内部服务调用,外部请求或直接浏览器访问会被拒绝。

如果你希望实现内部调用不鉴权,就需要发起者加上@NoToken 接口提供方加上@Inner

@Inner 的设计初衷是 只允许内部服务调用

@EnableDmsFeignClients注解

当你的项目需要通过 Feign 调用其他服务(即 “请求别人”)时,需要在配置类上添加这个注解来启用相关功能。


评论