使用带有kid和JWKS的spring-security-oauth2授权服务器?

问题描述 投票:3回答:1

根据文档herethere,我设法建立了一个授权服务器,该服务器给出了使用非对称密钥签名的JWT访问令牌,资源服务器使用公钥的本地副本在本地验证。到现在为止还挺好。

我的最终目标是资源服务器在授权服务器上使用JWKS端点,并使用JWT中的'kid'标头在JWKS中查找正确的密钥并在本地验证,支持密钥轮换。我找到了how to make the Authorization Server expose a JWKS endpoint,还有how to specify the key-set-uri for the resource server

但是,似乎没有办法

  • 在JWKS中发布kid(key id)值
  • 包括JWT中的kid标题

有没有办法做到这一点?

jwt spring-security-oauth2 jwk
1个回答
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的标题中设置它。


1
投票

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

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

因此,将KID放在JwkSetEndpoint中将导致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。

© www.soinside.com 2019 - 2024. All rights reserved.