3

按照这里那里的文档,我设法设置了一个授权服务器,它发出使用非对称密钥签名的 JWT 访问令牌,资源服务器使用公钥的本地副本在本地验证这些令牌。到目前为止,一切都很好。

我的最终目标是让资源服务器在授权服务器上使用 JWKS 端点,并使用 JWT 中的“kid”标头在 JWKS 中查找正确的密钥并在本地验证,支持密钥轮换。我发现了如何让授权服务器公开一个 JWKS 端点,以及如何为资源服务器指定 key-set-uri

不过好像没有办法

  • 在 JWKS 中发布孩子(密钥 ID)值
  • 在 JWT 中包含 child 标头

有没有办法做到这一点?

4

2 回答 2

2

我找到了一种在 jwks 端点中设置孩子的方法:

@FrameworkEndpoint
public class JwkSetEndpoint {
    private final KeyPair keyPair;

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

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

我没有找到一种将其设置在 JWT 标头中的方法。

于 2019-03-15T09:07:48.103 回答
1

在遇到同样的问题时,我偶然发现了这篇文章。所以我希望它对某人有用。我不认为这是最好的解决方案,所以也许有人想出了一个更好的答案,我希望例如设置一些外部 bean。

背景:Jwk 存储正在将令牌标头中的 KID 与内存中的 KID 进行比较,如果不可用,它将请求众所周知的端点

因此,将 KID 放入 JwkSetEndpoint 会生成一个包含 child 的 json 文件。在此旁边,您需要获取 jwt 令牌标头上的 KID。

我在课堂上的解决方案扩展了 JwtAccessTokenConverter

@Override
protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    String content = null;
    try {
        content = objectMapper.formatMap(getAccessTokenConverter().convertAccessToken(accessToken, authentication));
    } catch (Exception e) {
        throw new IllegalStateException("Cannot convert access token to JSON", e);
    }
    Map<String, String> headers = getJwtHeader();

    String token = JwtHelper.encode(content, signer, headers).getEncoded();
    return token;
}

在 KID 标头旁边,Tokenstore 期望使用标头设置为签名。我还必须覆盖签名者对象,因为我被 hmac 签名者而不是所需的 RsaSigner 卡住了。

于 2019-07-04T14:16:10.170 回答