自定义Spring OAuth2TokenEndpointFilter认证成功处理器无效问题排查
解决方法
你的问题出在三个核心点上:
- 直接修改原参数Map无效:
accessTokenAuthentication.getAdditionalParameters()返回的是不可修改的Map,或是原对象的引用,后续框架逻辑可能会覆盖你的修改;而且设置null值不会移除字段,框架依然会输出默认值。 - 未正确控制响应字段:默认的
OAuth2AccessTokenResponse会自动包含token_type、expires_in等标准字段,你需要通过Builder显式选择是否包含这些字段,而非仅修改附加参数。 - 自定义Filter未被正确加载:Spring Authorization Server内部已注册默认的
OAuth2TokenEndpointFilter,若自定义Bean未指定匹配路径或同步配置,可能不会替换默认实例,导致逻辑不生效。
修正后的代码示例:
@Bean public OAuth2TokenEndpointFilter oauth2TokenEndpointFilter(AuthenticationManager authenticationManager, OAuth2TokenEndpointConfigurer tokenEndpointConfigurer) { // 指定Token端点路径,与默认端点保持一致 OAuth2TokenEndpointFilter filter = new OAuth2TokenEndpointFilter(authenticationManager, "/oauth2/token"); filter.setAuthenticationSuccessHandler((request, response, authentication) -> { OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = (OAuth2AccessTokenAuthenticationToken) authentication; OAuth2AccessToken accessToken = accessTokenAuthentication.getAccessToken(); OAuth2RefreshToken refreshToken = accessTokenAuthentication.getRefreshToken(); // 创建新的可修改Map,避免直接操作原对象 Map<String, Object> customParameters = new HashMap<>(); // 仅添加需要的自定义字段,不需要的字段不加入 customParameters.put("user_id", "你的自定义用户ID"); // 构建自定义响应,按需选择包含的字段 OAuth2AccessTokenResponse.Builder responseBuilder = OAuth2AccessTokenResponse.withToken(accessToken.getTokenValue()) .tokenType(accessToken.getTokenType()); // 按需添加refresh_token,不需要则注释 if (refreshToken != null) { responseBuilder.refreshToken(refreshToken.getTokenValue()); } // 添加自定义参数 responseBuilder.additionalParameters(customParameters); // 不调用expiresIn()方法,响应就不会包含expires_in字段 OAuth2AccessTokenResponse accessTokenResponse = responseBuilder.build(); // 设置响应头并输出 ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response); httpResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON); new OAuth2AccessTokenResponseHttpMessageConverter().write(accessTokenResponse, null, httpResponse); }); // 同步默认端点的配置,确保Filter能正常工作 filter.setSecurityContextRepository(tokenEndpointConfigurer.getSecurityContextRepository()); filter.setAuthenticationConverter(tokenEndpointConfigurer.getAuthenticationConverter()); filter.setAuthenticationFailureHandler(tokenEndpointConfigurer.getAuthenticationFailureHandler()); return filter; }
额外注意事项:
- 确保替换默认Filter:Spring会优先使用自定义的
OAuth2TokenEndpointFilterBean,若存在多个实例,可通过指定Bean名称保证优先级。 - 精准控制响应字段:
OAuth2AccessTokenResponse.Builder的方法是可选的,不需要的字段不要调用对应的方法,比如不需要expires_in就不调用expiresIn(),这样响应中就不会出现该字段。 - 避免修改原Authentication对象:永远不要直接修改
Authentication内部的参数,应创建新的容器构建自定义响应,防止框架后续逻辑覆盖你的修改。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

