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

Spring Authentication Server认证流程

SAS认证过程解析

1.OAuth2/SAS

先简单了解一下OAuth2的授权体系(以项目的用户密码模式为例)

+-----------------+        +---------------------+        +-----------------+
|                 |        |                     |        |                 |
|    客户端应用    |        |   授权服务器 (SAS)   |        |   资源服务器     |
|   (Web/移动端)  |        |                     |        |   (API/服务)    |
+--------+--------+        +----------+----------+        +--------+--------+
         |                             |                             |
         | 1. 用户输入用户名和密码     |                             |
         |---------------------------->|                             |
         |                             |                             |
         |                             | 2. 验证用户名和密码          |
         |                             |---------------------------->|
         |                             |                             |
         |                             | 3. 颁发 Access Token (+Refresh Token) |
         |                             |<----------------------------|
         | 4. 客户端收到 Access Token  |                             |
         |<----------------------------|                             |
         |                             |                             |
         | 5. 使用 Access Token 请求资源 |                             |
         |---------------------------->|                             |
         |                             | 6. 验证 Access Token         |
         |                             |---------------------------->|
         |                             |                             |
         |                             | 7. 返回受保护资源数据        |
         |<----------------------------|                             |

2.主流程(示例流程)

在网上示例的主流程中,表述并不清晰,我们不知道这些模块属于谁,也不知道OAuth2的标准体系应该有什么,哪些是自己包含的,哪些又是需要自己写的

3.代码结合

需要弄清楚到底需要写什么,哪些是Spring Authentication Server自带的需要实现和配置的

其实真正的调用主流程都在AuthorizationServerConfiguration里面

方法执行顺序解析

过滤器

http.securityMatcher("/oauth2/**")

表示只有匹配 /oauth2/** 的请求才进入这个 FilterChain。
其他路径走别的安全配置。

http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)

这里手动往 Spring Security 的过滤器链中插入一个 ValidateCodeFilter(验证码验证过滤器)。
它是继承 OncePerRequestFilter 的自定义过滤器。
它的位置在 UsernamePasswordAuthenticationFilter 之前

ValidateCodeFilter

PasswordDecoderFilter

UsernamePasswordAuthenticationFilter

OAuth2TokenEndpointFilter(SAS自带)

其中大概的流程

用户请求 /oauth2/token
        ↓
进入 SecurityFilterChain(authorizationServer)
        ↓
执行 ValidateCodeFilter (验证码)
        ↓
执行 PasswordDecoderFilter (解密密码)
        ↓
进入 OAuth2TokenEndpointFilter (OncePerRequestFilter)
        ↓
由 accessTokenRequestConverter 识别模式(如 password)
        ↓
调用 OAuth2ResourceOwnerPasswordAuthenticationProvider
        ↓
认证成功 → DmsAuthenticationSuccessEventHandler
认证失败 → DmsAuthenticationFailureEventHandler
        ↓
生成 Token (通过 CustomOAuth2AccessTokenGenerator)
        ↓
返回 access_token 响应

重点:自定义 Converter 和 Provider

OAuth2TokenEndpointFilter作为SAS框架的接口控制器,那么它的下一步会做什么呢

我们需要控制它,所以为他配置转换器

http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {
    // 个性化认证授权端点
               tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) 
                   // 注入自定义的授权认证Converter
                     .accessTokenResponseHandler(new DmsAuthenticationSuccessEventHandler()) 
                   // 登录成功处理器
                     .errorResponseHandler(new DmsAuthenticationFailureEventHandler());
                   // 登录失败处理器
            })

accessTokenRequestConverter是什么呢?它是自定义处理链的集合

如果不做自定义配置,他就无法支持诸如微信登录,短信登录

@Bean
	public AuthenticationConverter accessTokenRequestConverter() {
		return new DelegatingAuthenticationConverter(Arrays.asList(
				new OAuth2ResourceOwnerPasswordAuthenticationConverter(),
				new OAuth2RefreshTokenAuthenticationConverter(),
				new OAuth2ClientCredentialsAuthenticationConverter()));
	}

OAuth2ResourceOwnerPasswordAuthenticationConverter 即是我们的最普通的登录的密码模式的请求转换器

在SAS标准流程中,自己的Token对象 + Convert + Provider即可配置新的认证方式

// 注入自定义授权模式实现
		addCustomOAuth2GrantAuthenticationProvider(http);

什么是Convert ?Provider又是什么?

在SAS流程中,Authentication对象是他们传递的对象主体,一般我们自己的token对象需要实现这个接口

当上方过滤器完成后的请求形成了request之后

当然在流程的provider之中,密码模式还需要实现一个DAOprovider,因为需要查库校验密码,还不能直接生成token,也就是项目中的DmsDaoAuthenticationProvider

它封装了 用户名/密码认证的公共流程

  1. 调用 retrieveUser() 获取用户信息
  2. 调用 additionalAuthenticationChecks() 校验密码

3.项目设计

在认证流程中,auth模块是负主要职责的,所以大部分实现可以完全由auth掌管,但是我们既然希望token可以被管理,那么其中的AuthenticationService就可以被复用操作token,所以可以抽到公共类中。

1.首先是配置类,其中注入了所有我们定义的类,包括过滤器,指定的convert,使用的provider。

2.如果拓展短信和微信登录,直接参考password

3.DmsDaoAuthenticationProvider被谁调用?被我们password的provider调用,实现密码校验; 为什么不自己实现密码校验逻辑,因为职责分离,调用manager的认证,它能够帮我们自动调用合适的provider去校验

4.CustomOAuth2AccessTokenGenerator是为了自定义令牌的生成逻辑,它并非是access-token的生成逻辑,而是客户端可用的 token 字符串 + 对应权限上下文信息

5.token的增删改查放在哪?准备放在公共类中,因为admin需要维护,DmsRedisOAuth2AuthorizationService


评论