Jwt 将spring-security-oauth2授权服务器与kid和JWKS一起使用?

Jwt 将spring-security-oauth2授权服务器与kid和JWKS一起使用?,jwt,spring-security-oauth2,jwk,Jwt,Spring Security Oauth2,Jwk,在文档和文档之后,我成功地设置了一个授权服务器,该服务器提供使用非对称密钥签名的JWT访问令牌,资源服务器使用公钥的本地副本在本地验证这些令牌。到目前为止还不错 我的最终目标是让资源服务器在授权服务器上使用JWKS端点,并使用JWT中的“kid”头在JWKS中查找正确的密钥并在本地进行验证,从而支持密钥轮换。 我找到了,也找到了 然而,似乎没有办法 在JWKS中发布kid(键id)值 在JWT中包括kid头 有什么方法可以做到这一点吗?我找到了在jwks端点中设置孩子的方法: @Framew

在文档和文档之后,我成功地设置了一个授权服务器,该服务器提供使用非对称密钥签名的JWT访问令牌,资源服务器使用公钥的本地副本在本地验证这些令牌。到目前为止还不错

我的最终目标是让资源服务器在授权服务器上使用JWKS端点,并使用JWT中的“kid”头在JWKS中查找正确的密钥并在本地进行验证,从而支持密钥轮换。 我找到了,也找到了

然而,似乎没有办法

  • 在JWKS中发布kid(键id)值
  • 在JWT中包括kid头

有什么方法可以做到这一点吗?

我找到了在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();
    }
}

@FrameworkEndpoint
公共类JwkSetEndpoint{
私有最终密钥对密钥对;
公共JwkSetEndpoint(密钥对密钥对){
this.keyPair=keyPair;
}
@GetMapping(“/.well-known/jwks.json”)
@应答器
公共映射getKey(){
RSAPublicKey publicKey=(RSAPublicKey)this.keyPair.getPublic();
RSAKey key=new RSAKey.Builder(publicKey)
.keyID(“你的孩子在这里”)
.keyUse(keyUse.SIGNATURE).build();
返回新的JWKSet(key).toJSONObject();
}
}

我没有找到在JWT的标题中设置它的方法。

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

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

因此,将KID放入JwkSetEndpoint将生成一个包含KID的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;
}
@覆盖
受保护的字符串编码(OAuth2AccessToken accessToken,OAuth2Authentication身份验证){
字符串内容=null;
试一试{
content=objectMapper.formatMap(getAccessTokenConverter().convertAccessToken(accessToken,身份验证));
}捕获(例外e){
抛出新的IllegalStateException(“无法将访问令牌转换为JSON”,e);
}
Map headers=getJwtHeader();
字符串标记=JwtHelper.encode(内容、签名者、标题).getEncoded();
返回令牌;
}
在KID标头旁边,Tokenstore希望将use标头设置为signing。 我还必须重写signer对象,因为我被一个hmac签名者而不是所需的RsaSigner卡住了