Spring Reactive Security OAuth2 PKCE登录时code_verifier未发送
问题解答
1. code_verifier未自动携带的原因及配置方法
你遇到的code_verifier缺失问题,核心原因是手动在authorization-uri配置项中硬编码了code_challenge、code_challenge_method等PKCE相关参数,直接触发了Spring Security的跳过逻辑,框架不会再自动生成、传递code_verifier。
Spring Security 5.6及以上版本(对应Spring Boot 2.6+)的响应式OAuth2 Login模块,默认会为授权码流程自动处理全链路PKCE逻辑:
- 生成符合RFC规范的随机
code_verifier存入会话 - 根据配置的challenge方法计算对应
code_challenge - 发起授权请求时自动拼接所有必要参数到授权URI
- 收到授权回调兑换token时,自动从会话取出code_verifier携带到token请求中
这个流程不需要额外注册自定义Bean,只要修正yaml配置即可:
- 移除
authorization-uri后面拼接的所有query参数,仅保留基础接口地址 - 将scope等配置移到registration对应配置项下,不要硬编码到URI中
修正后的配置参考:
spring: security: oauth2: client: registration: twitter: client-id: xxx client-secret: xxx authorization-grant-type: authorization_code redirect-uri: http://localhost:8080/login/oauth2/code/twitter scope: tweet.read,users.read,follows.read,follows.write # 若你的Twitter应用为无client-secret的公共客户端,添加下行强制启用PKCE # client-authentication-method: none provider: twitter: authorization-uri: https://twitter.com/i/oauth2/authorize token-uri: https://api.twitter.com/2/oauth2/token user-info-uri: https://api.twitter.com/2/users/me user-name-attribute: data
如果使用5.6以下的Spring Security版本,才需要手动注册ReactiveOAuth2AuthorizationRequestResolver实例启用PKCE,目前主流的Spring Boot版本不需要额外配置。
2. 自定义ReactiveOAuth2AccessTokenResponseClient的支持情况
完全支持自定义,你可以通过该扩展点修改发往token端点的请求体、请求头、参数格式等内容,配置方式是在oauth2Login配置项中注入自定义实例即可,示例如下:
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { ServerOAuth2AuthorizationCodeTokenResponseClient customTokenClient = new ServerOAuth2AuthorizationCodeTokenResponseClient(); // 自定义WebClient拦截修改请求 WebClient customWebClient = WebClient.builder() .filter((request, next) -> { // 在此处修改请求头、请求体内容,比如添加Twitter要求的特殊参数 return next.exchange(request); }) .build(); customTokenClient.setWebClient(customWebClient); return http.authorizeExchange() .anyExchange().authenticated() .and() .oauth2Login() .tokenEndpoint(tokenConfig -> tokenConfig.accessTokenResponseClient(customTokenClient)) .build(); }
如果需要更细粒度地调整token请求的表单参数,可以替换客户端内部的参数转换器,自定义参数构造逻辑即可。
注意:Twitter的OAuth2 token端点强制要求携带code_verifier参数,无论客户端类型是公共客户端还是机密客户端,不要手动硬编码code_challenge固定值,交给框架自动生成即可避免签名校验失败。
内容的提问来源于stack exchange,提问作者momonosuke__
相关产品推荐
相关产品推荐

