Spring Authorization Server启用OIDC与不透明令牌的配置冲突求助
问题背景
需要在Spring Authorization Server中同时启用OIDC和不透明令牌功能。启用OIDC后,客户端调用/userinfo端点时,使用不透明Bearer令牌会因无法被识别而报错。尝试配置自定义authenticationManagerResolver:
.oauth2ResourceServer(resourceServer -> resourceServer .authenticationManagerResolver(authenticationManagerResolver(resourceServerProperties)));
但出现新错误,原因是启用OIDC时,OAuth2AuthorizationServerConfigurer会自动配置jwt:
OidcConfigurer oidcConfigurer = getConfigurer(OidcConfigurer.class); if (oidcConfigurer != null) { if (oidcConfigurer.getConfigurer(OidcUserInfoEndpointConfigurer.class) != null || oidcConfigurer.getConfigurer(OidcClientRegistrationEndpointConfigurer.class) != null) { httpSecurity // Accept access tokens for User Info and/or Client Registration .oauth2ResourceServer( (oauth2ResourceServer) -> oauth2ResourceServer.jwt(Customizer.withDefaults())); } }
错误堆栈如下:
Caused by: java.lang.IllegalStateException: If an authenticationManagerResolver() is configured, then it takes precedence over any jwt() or opaqueToken() configuration. at org.springframework.util.Assert.state(Assert.java:79) ~[spring-core-6.2.0.jar:6.2.0] at org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer.validateConfiguration(OAuth2ResourceServerConfigurer.java:299) ~[spring-security-config-6.4.1.jar:6.4.1] at org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer.init(OAuth2ResourceServerConfigurer.java:260) ~[spring-security-config-6.4.1.jar:6.4.1] at org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer.init(OAuth2ResourceServerConfigurer.java:147) ~[spring-security-config-6.4.1.jar:6.4.1] at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:366) ~[spring-security-config-6.4.1.jar:6.4.1] at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:328) ~[spring-security-config-6.4.1.jar:6.4.1] at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:38) ~[spring-security-config-6.4.1.jar:6.4.1] at app.chameleon.authorization.server.config.AuthorizationServerConfig.authorizationServerSecurityFilterChain(AuthorizationServerConfig.java:143) ~[classes/:na] at app.chameleon.authorization.server.config.AuthorizationServerConfig$$SpringCGLIB$$0.CGLIB$authorizationServerSecurityFilterChain$9(<generated>) ~[classes/:na] at app.chameleon.authorization.server.config.AuthorizationServerConfig$$SpringCGLIB$$FastClass$$1.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.2.0.jar:6.2.0] at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:348) ~[spring-context-6.2.0.jar:6.2.0] at app.chameleon.authorization.server.config.AuthorizationServerConfig$$SpringCGLIB$$0.authorizationServerSecurityFilterChain(<generated>) ~[classes/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.2.0.jar:6.2.0] ... 42 common frames omitted
解决方案
1. 自定义AuthenticationManagerResolver,同时支持JWT和不透明令牌
创建一个BearerTokenAuthenticationManagerResolver的实现,根据令牌格式判断使用对应认证管理器:
@Component public class MultiTokenAuthenticationManagerResolver implements AuthenticationManagerResolver<HttpServletRequest> { private final AuthenticationManager jwtAuthenticationManager; private final AuthenticationManager opaqueTokenAuthenticationManager; public MultiTokenAuthenticationManagerResolver(JwtDecoder jwtDecoder, OAuth2TokenIntrospector introspector) { this.jwtAuthenticationManager = new JwtAuthenticationProvider(jwtDecoder)::authenticate; this.opaqueTokenAuthenticationManager = new OpaqueTokenAuthenticationProvider(introspector)::authenticate; } @Override public AuthenticationManager resolve(HttpServletRequest request) { String token = extractToken(request); if (token != null && isJwt(token)) { return jwtAuthenticationManager; } return opaqueTokenAuthenticationManager; } private String extractToken(HttpServletRequest request) { String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION); if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { return authorizationHeader.substring(7); } return null; } private boolean isJwt(String token) { return token.split("\\.").length == 3; // JWT为三段式结构 } }
2. 覆盖OIDC自动配置,使用自定义Resolver
在授权服务器的SecurityFilterChain配置中,显式指定使用自定义Resolver,覆盖OIDC自动配置的JWT设置:
@Configuration public class AuthorizationServerConfig { @Autowired private MultiTokenAuthenticationManagerResolver authenticationManagerResolver; @Bean @Order(0) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); // 启用OIDC功能 http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .oidc(Customizer.withDefaults()); // 配置资源服务器使用自定义Resolver,覆盖自动配置的JWT http.oauth2ResourceServer(resourceServer -> resourceServer.authenticationManagerResolver(authenticationManagerResolver)); return http.build(); } // 配置JWT解码器 @Bean public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } // 配置不透明令牌校验器 @Bean public OAuth2TokenIntrospector opaqueTokenIntrospector() { return new NimbusOpaqueTokenIntrospector( "http://localhost:8080/oauth2/introspect", "your-client-id", "your-client-secret" ); } }
3. 关键说明
- 错误核心是同时配置
authenticationManagerResolver与jwt()/opaqueToken(),Spring Security不允许这种冲突配置,必须二选一。 - 自定义Resolver需自行实现令牌类型判断逻辑,确保JWT和不透明令牌能被正确路由到对应认证管理器。
- 需确保
OAuth2TokenIntrospector配置正确,用于校验不透明令牌的有效性。
内容的提问来源于stack exchange,提问作者Malvin
相关产品推荐
相关产品推荐

