在kid和JWKS上使用spring-security-oauth2授权服务器?

时间:2018-12-30 23:12:11

标签: jwt spring-security-oauth2 jwk

在文档herethere之后,我设法建立了一个授权服务器,该服务器提供了用非对称密钥签名的JWT访问令牌,这些令牌由资源服务器使用该证书的本地副本在本地进行验证。公钥。到目前为止一切顺利。

我的最终目标是让资源服务器使用授权服务器上的JWKS端点,并使用JWT中的“ kid”标头在JWKS中查找正确的密钥并在本地进行验证,以支持密钥旋转。 我找到了how to make the Authorization Server expose a JWKS endpointhow to specify the key-set-uri for the resource server

但是,似乎没有办法

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

有没有办法做到这一点?

2 个答案:

答案 0 :(得分: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 :(得分: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标头旁边

将use标头设置为签名。 我还必须覆盖签署者对象,因为我被hmac签署者卡住了,而不是想要的RsaSigner。