You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Security 5自定义OAuth2客户端配置缺失问题咨询

解决Spring Boot Security OAuth2客户端登录回调报错问题

Hey there, let's work through your issue with the custom OAuth2 provider in Spring Boot Security 5 step by step.

第一个问题:jwk-set-uri是否应由认证提供商提供?

简单来说:是的,这个URI应该由你的OAuth2/OpenID Connect提供商提供。

这里的背景是:当你配置了openid scope时,你的应用会从提供商那里获取一个ID Token(OpenID Connect的核心凭证)。Spring Security需要验证这个ID Token的签名,确保它确实来自合法的提供商且未被篡改。而jwk-set-uri就是提供商暴露的端点,用来获取一组JSON Web Keys(JWKs)——这些公钥就是用来验证ID Token签名的。

大多数正规的OpenID Connect提供商都会在他们的well-known配置端点里暴露这个URI,你可以尝试访问:

https://api.xxxxxxxxx.com/.well-known/openid-configuration

这个返回的JSON里应该有一个jwks_uri字段,那就是你需要的jwk-set-uri值。

你的配置缺失了什么?

核心问题在于:你启用了openid scope,但Spring Security无法获取到验证ID Token签名所需的公钥,所以在登录回调时抛出错误。

针对你的情况,有几个可行的解决方向:

1. 确认并配置提供商的JWK端点

先按照上面的方法访问提供商的well-known配置地址,看看是否有jwks_uri。如果有,把它添加到你的application.properties里:

spring.security.oauth2.client.provider.xxxxxxxxx.jwk-set-uri=https://api.xxxxxxxxx.com/your-jwk-endpoint

这是最直接且规范的解决方案。

2. 移除openid scope(如果不需要ID Token)

如果你不需要ID Token,只是想获取Access Token来调用提供商的API,或者已经通过user-info-uri获取用户信息,那可以去掉openid scope。修改配置:

spring.security.oauth2.client.registration.xxxxxxxxx.scope= # 这里改成你需要的业务相关scope,比如API访问权限,或留空如果不需要额外权限

这样Spring Security就不会尝试处理ID Token,也就不再需要jwk-set-uri配置了。

3. 自定义JwtDecoder(如果提供商提供静态公钥)

如果提供商确实没有JWK端点,但给了你静态的公钥(比如PEM格式),那你需要写一个简单的配置类来创建JwtDecoder,用这个公钥验证ID Token。虽然你提到项目只用application.properties,但这是这种场景下的必要操作。示例代码大概是这样:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import java.security.interfaces.RSAPublicKey;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

@Configuration
public class OAuth2Config {
    @Bean
    public JwtDecoder jwtDecoder() throws Exception {
        // 从PEM文件加载公钥,替换成你的公钥路径或字符串
        String publicKeyPEM = new String(Files.readAllBytes(Paths.get("path/to/public-key.pem")))
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
                .replaceAll("\\s", "");
        
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyPEM);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
        
        return NimbusJwtDecoder.withPublicKey(publicKey).build();
    }
}

总结

优先尝试第一种方法,确认提供商的JWK端点是否存在。如果没有,再考虑移除openid scope或者自定义JwtDecoder。如果提供商既没有JWK端点也不提供静态公钥,那他们的OpenID Connect实现可能不符合规范,建议联系他们的技术支持确认。

内容的提问来源于stack exchange,提问作者Ankur Raiyani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:25:37