如何为 spring oauth2 jwt 服务器生成正确的 jwks 端点?

Posted

技术标签:

【中文标题】如何为 spring oauth2 jwt 服务器生成正确的 jwks 端点?【英文标题】:How to produce correct jwks endpoint for spring oauth2 jwt server? 【发布时间】:2020-07-16 12:06:35 【问题描述】:

发布的目标

使用有效的jwks为我的spring oauth2 jwt服务器配置/.well-known/jwks.json

第一次尝试

在spring documentation 之后,我可以使用 JWK 设置 URI 的框端点。它需要:

@Import(AuthorizationServerEndpointsConfiguration.class)

我已经添加了。通过执行器检查映射的端点,没有过滤jw

第二次尝试

按照我尝试使用下一个代码的相同配置:

import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
...

@FrameworkEndpoint
class JwkSetEndpoint 
    KeyPair keyPair;

    public JwkSetEndpoint(KeyPair keyPair) 
        this.keyPair = keyPair;
    

    @GetMapping("/.well-known/jwks.json")
    @ResponseBody
    public Map<String, Object> getKey(Principal principal) 
        RSAPublicKey publicKey = (RSAPublicKey) this.keyPair.getPublic();
        RSAKey key = new RSAKey.Builder(publicKey).build();
        return new JWKSet(key).toJSONObject();
    

它产生


  "keys" : [ 
    "kty" : "RSA",
    "e" : "AQAB",
    "n" : "mWI2jtKwvf0W1hdMdajch-mFx9FZe3CZnKNvT_d0-2O6V1Pgkz7L2FcQx2uoV7gHgk5mmb2MZUsy_rDKj0dMfLzyXqBcCRxD6avALwu8AAiGRxe2dl8HqIHyo7P4R1nUaea1WCZB_i7AxZNAQtcCcSvMvF2t33p3vYXY6SqMucMD4yHOTXexoWhzwRqjyyC8I8uCYJ-xIfQvaK9Q1RzKRj99IRa1qyNgdeHjkwW9v2Fd4O_Ln1Tzfnk_dMLqxaNsXPw37nw-OUhycFDPPQF_H4Q4-UDJ3ATf5Z2yQKkUQlD45OO2mIXjkWprAmOCi76dLB2yzhCX_plGJwcgb8XHEQ"
   ]

使用 access_token ping 资源服务器失败:

"error":"invalid_token","error_description":"Invalid JWT/JWS: kid is a required JOSE Header"

第三次尝试

修改"/.well-known/jwks.json" (jwt.io helps detect algorithm used for jwt) 的响应:

        RSAKey key = new RSAKey.Builder(publicKey)
                .keyID("1")
                .keyUse(KeyUse.SIGNATURE)
                .algorithm(JWSAlgorithm.RS256)
                .build();

导致下一个响应:


  "keys" : [ 
    "kty" : "RSA",
    "e" : "AQAB",
    "use" : "sig",
    "kid" : "1",
    "alg" : "RS256",
    "n" : "mWI2jtKwvf0W1hdMdajch-mFx9FZe3CZnKNvT_d0-2O6V1Pgkz7L2FcQx2uoV7gHgk5mmb2MZUsy_rDKj0dMfLzyXqBcCRxD6avALwu8AAiGRxe2dl8HqIHyo7P4R1nUaea1WCZB_i7AxZNAQtcCcSvMvF2t33p3vYXY6SqMucMD4yHOTXexoWhzwRqjyyC8I8uCYJ-xIfQvaK9Q1RzKRj99IRa1qyNgdeHjkwW9v2Fd4O_Ln1Tzfnk_dMLqxaNsXPw37nw-OUhycFDPPQF_H4Q4-UDJ3ATf5Z2yQKkUQlD45OO2mIXjkWprAmOCi76dLB2yzhCX_plGJwcgb8XHEQ"
   ]

使用 access_token ping 资源服务器提供相同的结果:

"error":"invalid_token","error_description":"Invalid JWT/JWS: kid is a required JOSE Header"

问题

是否有任何想法或示例如何配置/.well-known/jwks.json 以产生正确的jwks

附言

如果我在资源服务器上使用公钥作为本地资源 - 它可以工作。 我很乐意提供任何可行的解决方案(可能有人知道可以在 spring-boot 应用程序中使用的不同 jwks 库)。

【问题讨论】:

【参考方案1】:

对此有何更新?

我们正在研究基于签名的身份验证,https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12,

其中一个要求是实现 /.well-known/jwks.json 端点,因此我们不必有单独的公钥分发机制。

我还没有这样做,但它看起来像:

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    return JWKSet.load(keyStore, (name) -> null).toPublicJWKSet();

【讨论】:

以上是关于如何为 spring oauth2 jwt 服务器生成正确的 jwks 端点?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 OAuth2 访问令牌指定受众?

如何为 spring webflux 应用程序配置 oauth2 资源服务器?

Spring Security - OAuth2 和 CustomAuthenticationProvider。如何为每个配置不同的 URL 模式?

Spring Boot 2 和 OAuth2/JWT

Spring Boot Security OAuth2 实现支持JWT令牌的授权服务器

Oauth2 Spring中的JWT令牌