Spring Authorization Server 1.1.1中OIDC的sid与auth_time为空致刷新报错
解决方案与auth_time配置建议
问题回顾
你提到升级到spring-boot-starter-oauth2-authorization-server 3.1.3后,刷新令牌时的500错误已解决——这是因为新版本修复了旧版本中JwtGenerator在刷新流程中无法正确从原IdToken读取sid和auth_time的问题,现在这两个claim会自动继承自首次认证的IdToken,无需手动添加。
配置auth_time实现定时重认证
要利用auth_time实现定时强制重认证,需结合OIDC标准的max_age参数和授权服务器的会话管理策略,具体步骤如下:
客户端请求触发重认证检查
客户端在发起授权请求时,携带max_age参数(例如max_age=3600),表示若用户上次认证时间距当前超过3600秒,必须重新进行身份验证。授权服务器端会话与认证时间管理
- 配置会话超时:通过
SecurityFilterChain中的会话管理规则,设置会话的最大空闲时间或绝对过期时间,示例:@Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { http .sessionManagement(session -> session .sessionFixation().migrateSession() .maximumSessions(1) .expiredUrl("/login?expired") .maxSessionsPreventsLogin(true) ); // 其他授权服务器配置... return http.build(); } - 确保
auth_time正确生成:升级后的版本会在首次认证时自动设置auth_time,若需自定义(比如统一用UTC时间),可在JwtTokenCustomizer中补充:if (OidcParameterNames.ID_TOKEN.equalsIgnoreCase(context.getTokenType().getValue())) { if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(context.getAuthorizationGrantType())) { // 首次认证时设置auth_time为当前时间戳(秒级) long authTime = Instant.now().getEpochSecond(); context.getClaims().claim(IdTokenClaimNames.AUTH_TIME, authTime); } }
- 配置会话超时:通过
资源服务器验证auth_time
资源服务器在接收令牌时,需验证auth_time是否满足客户端指定的max_age要求,拒绝超时的令牌。可通过自定义JWT验证逻辑实现:@Bean public JwtAuthenticationConverter jwtAuthenticationConverter() { JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); converter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthoritiesConverter()); converter.setPrincipalClaimName("sub"); // 添加auth_time验证逻辑 converter.setJwtValidator(jwt -> { Instant authTime = jwt.getClaimAsInstant(IdTokenClaimNames.AUTH_TIME); if (authTime == null) { return OAuth2Error.withErrorCode(OAuth2ErrorCodes.INVALID_TOKEN) .description("Missing auth_time claim") .build(); } // 假设从请求参数或客户端配置获取max_age long maxAge = 3600; if (Instant.now().minusSeconds(maxAge).isAfter(authTime)) { return OAuth2Error.withErrorCode(OAuth2ErrorCodes.INVALID_TOKEN) .description("Authentication expired") .build(); } return OAuth2AuthenticationValidatorResult.success(); }); return converter; }完善重认证流程
- 配置客户端的
postLogoutRedirectUri,确保用户重认证后能正确跳转回业务页面。 - 授权服务器端配置
logoutSuccessUrl,处理会话过期或重认证后的跳转逻辑。
- 配置客户端的
关键注意事项
auth_time在刷新令牌时会自动继承首次认证的值,无需手动修改,确保用户认证状态的一致性。- 定时重认证的触发依赖客户端主动携带
max_age参数,授权服务器不会主动强制重认证,除非会话已过期。 - 若需全局强制重认证策略,可自定义
OAuth2AuthorizationService,在刷新令牌时检查auth_time是否超过阈值,拒绝刷新请求并引导用户重新认证。
内容的提问来源于stack exchange,提问作者Jeffrey Brown
相关产品推荐
相关产品推荐

