Spring Boot Resource Server配置jwk-set-uri后报Invalid Access Token问题
问题根因
- 注解与配置属性不匹配:你当前使用的
@EnableResourceServer是Spring Security OAuth2项目的遗留资源服务实现,该实现已停止维护,它只会读取security.oauth2.resource.*前缀的配置,你配置的spring.security.oauth2.resourceserver.jwt.jwk-set-uri是Spring Security 5+原生内置资源服务的专属配置,遗留实现不会加载该配置,因此注释自定义Jwt转换器后,资源服务没有可用的公钥校验令牌,直接返回无效。 - 端点类型不匹配:如果你的授权服务
/oauth/token_key接口返回的是单个PEM格式公钥,而非JWKS(JSON Web Key Set)集合,即使切换到原生资源服务,直接配置jwk-set-uri也会校验失败,该属性仅支持JWKS格式接口。
解决方案
方案1:继续使用遗留@EnableResourceServer实现
- 修改application.properties配置,注释新版属性,放开旧版属性:
# 注释掉新版资源服务配置 # spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:9092/oauth/token_key # 启用旧版资源服务公钥拉取配置 security.oauth2.resource.jwt.key-uri=http://localhost:9092/oauth/token_key security.oauth2.resource.id=couponservice
- 确保项目已引入
spring-security-oauth2-autoconfigure依赖,保证旧版配置自动生效。
方案2:迁移到Spring Security原生资源服务(推荐,旧实现已废弃)
- 移除
@EnableResourceServer注解,删除继承ResourceServerConfigurerAdapter的配置类。 - 替换安全配置为原生资源服务配置,示例如下:
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.oauth2.jwt.JwtValidators; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator; import org.springframework.security.oauth2.core.OAuth2TokenValidator; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.JwtAudienceValidator; @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .mvcMatchers(HttpMethod.GET, "/couponapi/coupons/{code:^[A-Z]*$}").hasAnyRole("USER", "ADMIN") .mvcMatchers(HttpMethod.POST, "/couponapi/coupons").hasRole("ADMIN") .anyRequest().denyAll() ) .csrf(csrf -> csrf.disable()) .oauth2ResourceServer(oauth2 -> oauth2.jwt()); return http.build(); } // 可选:配置资源ID校验,匹配你之前定义的couponservice资源ID @Bean public JwtDecoder jwtDecoder() { // 如果授权服务的/token_key是JWKS格式则用withJwkSetUri,如果是单个公钥则用withPublicKey NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri("http://localhost:9092/oauth/token_key").build(); OAuth2TokenValidator<Jwt> audienceValidator = new JwtAudienceValidator("couponservice"); OAuth2TokenValidator<Jwt> defaultValidator = JwtValidators.createDefault(); jwtDecoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(defaultValidator, audienceValidator)); return jwtDecoder; } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
- 调整application.properties配置,根据你的授权服务端点类型选择对应配置:
- 如果是JWKS格式端点:保留
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:9092/oauth/token_key即可 - 如果是单个PEM公钥端点:使用如下配置,提前把公钥存到resources目录下:
spring.security.oauth2.resourceserver.jwt.public-key-location=classpath:public.key spring.security.oauth2.resourceserver.jwt.jws-algorithms=RS256
内容的提问来源于stack exchange,提问作者Arefe
相关产品推荐
相关产品推荐

