Spring Security OAuth2能否通过过滤器设置Token过期?如何解决空指针异常
问题解答
是否可通过过滤器实现动态设置Token过期时间?
可以,但需要正确适配Spring Security OAuth2的认证流程,不能破坏原有Token生成组件的依赖关系。过滤器的核心作用是传递动态过期时间参数,而非直接修改Token生成逻辑,避免因操作未初始化的组件引发异常。
如何解决authenticationKeyGenerator空指针异常?
该异常的本质是你在过滤器中手动实例化了Token相关组件(如DefaultTokenServices),而这些组件内部依赖的authenticationKeyGenerator等对象是由Spring容器自动装配的,手动new的实例无法获取这些依赖,导致空指针。以下是具体解决步骤:
1. 调整过滤器职责:仅传递动态参数
过滤器只负责从请求中提取动态过期时间,存入请求上下文,后续由原有TokenEnhancer处理,避免直接操作TokenServices。
@Component public class CustomTokenExpirationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 根据业务逻辑动态获取过期时间(示例:按客户端ID区分) String clientId = request.getParameter("client_id"); Long dynamicExpires = "mobile_client".equals(clientId) ? 3600L : 86400L; // 将过期时间存入请求属性,供后续TokenEnhancer读取 request.setAttribute("dynamic_expires_in", dynamicExpires); filterChain.doFilter(request, response); } }
2. 正确配置过滤器执行顺序
在授权服务器配置中,将过滤器添加到Token端点的认证过滤器链中,确保在Token生成前执行:
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private CustomTokenExpirationFilter customTokenExpirationFilter; @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { // 将自定义过滤器添加到Token端点的认证流程中 security.addTokenEndpointAuthenticationFilter(customTokenExpirationFilter); } // 其他原有配置(如TokenStore、TokenEnhancerChain等)保持不变 }
3. 修改原有AAACustomTokenEnhancer读取动态参数
在你的Token增强器中,从请求上下文获取动态过期时间并设置:
public class AAACustomTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) accessToken; // 从请求属性中读取动态过期时间 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); Long dynamicExpires = (Long) request.getAttribute("dynamic_expires_in"); if (dynamicExpires != null) { token.setExpiration(new Date(System.currentTimeMillis() + dynamicExpires * 1000)); } else { // 默认过期时间 token.setExpiration(new Date(System.currentTimeMillis() + 86400 * 1000)); } return token; } }
4. 确保请求上下文可用
如果项目中未配置请求上下文监听,需添加以下配置保证RequestContextHolder能获取当前请求:
@Configuration public class WebConfig implements WebMvcConfigurer { @Bean public RequestContextListener requestContextListener() { return new RequestContextListener(); } }
内容的提问来源于stack exchange,提问作者Parth
相关产品推荐
相关产品推荐

