【问题标题】:Using spring-security-oauth2 Authorization Server with kid and JWKS?将 spring-security-oauth2 授权服务器与 child 和 JWKS 一起使用?
【发布时间】:2019-05-27 16:13:07
【问题描述】:

按照文档 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 中发布孩子(密钥 id)值
  • 在 JWT 中包含 child 标头

有没有办法做到这一点?

【问题讨论】:

    标签: jwt spring-security-oauth2 jwk


    【解决方案1】:

    我找到了一种在 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 的标头中设置它的方法。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2015-05-22
        • 2020-07-23
        • 2018-09-26
        • 2013-12-01
        • 2015-03-31
        • 2021-10-29
        • 2020-03-14
        • 2016-05-21
        • 2014-07-09
        相关资源
        最近更新 更多