如何在Spring-Security 5.2中增加RemoteJWKSet缓存TTL [英] How to increase RemoteJWKSet cache TTL in spring-security 5.2

查看:627
本文介绍了如何在Spring-Security 5.2中增加RemoteJWKSet缓存TTL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用spring-security 5.2通过JWT验证来保护REST API.

We are using spring-security 5.2 for securing our REST API through JWT validation.

使用spring:security:oauth2:resourceserver:jwt:jwk-set-uri属性,我们指示远程JWKS端点 转换为Spring,然后根据此URI创建一个NimbusJwtDecoder. 再往下,将创建一个RemoteJWKSet对象,该对象将对JWKS端点的调用缓存为默认TTL为5分钟.

With the spring:security:oauth2:resourceserver:jwt:jwk-set-uri property we indicate the remote JWKS endpoint which translates into Spring creating a NimbusJwtDecoder based on this URI. Further down, a RemoteJWKSet object is created that caches the calls to the JWKS endpoint with a default TTL to 5 minutes.

是否有增加该TTL的方法以最小化远程呼叫? 也许在一个具有不同TTL的地方注入一个新的DefaultJWKSetCache实例? 将其尽可能长时间地保留在高速缓存中似乎是安全的,因为当我们收到带有未知孩子的令牌时,将恢复对JWKS端点的调用以更新密钥集.

Is there a way to increase this TTL to minimise the remote calls ? Maybe injecting a new DefaultJWKSetCache instance somewhere with a different TTL ? It seems safe to keep this in cache for as long as possible because when we receive a token with an unknown kid, the call to the JWKS endpoint will be resumed to update the key set.

用于检索密钥的调用堆栈为波纹管

The call stack for retrieving the key is bellow

JwtAuthenticationProvider
  public Authentication authenticate(Authentication authentication)
    ...
      jwt = this.jwtDecoder.decode(bearer.getToken())
    ...

o.s.security.oauth2.jwt.NimbusJwtDecoder
    public Jwt decode(String token)
    ...
      Jwt createdJwt = createJwt(token, jwt);
    ...

    private Jwt createJwt(String token, JWT parsedJwt)
    ...
      JWTClaimsSet jwtClaimsSet = this.jwtProcessor.process(parsedJwt, null);
    ....

DefaultJWTProcessor
      public JWTClaimsSet process(final JWT jwt, final C context)
        ...
          if (jwt instanceof SignedJWT) {
                return process((SignedJWT)jwt, context);
                }
        ...

      public JWTClaimsSet process(final SignedJWT signedJWT, final C context)
            ...
              List<? extends Key> keyCandidates = selectKeys(signedJWT.getHeader(), claimsSet, context);
          ...

      private List<? extends Key> selectKeys(final JWSHeader header, final JWTClaimsSet claimsSet, final C context)
        ....
          if (getJWSKeySelector() != null) {
                 return getJWSKeySelector().selectJWSKeys(header, context);
                 }      
        ....  


JWSVerificationKeySelector
  public List<Key> selectJWSKeys(final JWSHeader jwsHeader, final C context)
    ...
      List<JWK> jwkMatches = getJWKSource().get(new JWKSelector(jwkMatcher), context);
    ...

RemoteJWKSet
  public List<JWK> get(final JWKSelector jwkSelector, final C context)
  ...
    JWKSet jwkSet = jwkSetCache.get();
        if (jwkSet == null) {
            jwkSet = updateJWKSetFromURL();
        }
  ...


DefaultJWKSetCache  
  public JWKSet get() {

    if (isExpired()) {
      jwkSet = null; // clear
    }

    return jwkSet;
  }

安全依赖性:

+- org.springframework.boot:spring-boot-starter-security:jar:2.2.4.RELEASE:compile
|  +- org.springframework.security:spring-security-config:jar:5.2.1.RELEASE:compile
|  \- org.springframework.security:spring-security-web:jar:5.2.1.RELEASE:compile
+- org.springframework.security:spring-security-oauth2-jose:jar:5.2.2.RELEASE:compile
|  +- org.springframework.security:spring-security-core:jar:5.2.1.RELEASE:compile
|  \- org.springframework.security:spring-security-oauth2-core:jar:5.2.1.RELEASE:compile
+- com.nimbusds:nimbus-jose-jwt:jar:8.8:compile
|  +- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile
|  \- net.minidev:json-smart:jar:2.3:compile (version selected from constraint [1.3.1,2.3])
|     \- net.minidev:accessors-smart:jar:1.2:compile
|        \- org.ow2.asm:asm:jar:5.0.4:compile
+- org.springframework.security:spring-security-oauth2-resource-server:jar:5.2.1.RELEASE:compile

推荐答案

我最终做了以下事情:

    @Bean
    public JwtDecoder jwtDecoder() {
        JWSKeySelector<SecurityContext> jwsKeySelector = null;
        try {
            URL jwksUrl = new URL("https://localhost/.well-known/openid-configuration/jwks");
            long cacheLifespan = 500;
            long refreshTime = 400;
            JWKSetCache jwkSetCache = new DefaultJWKSetCache(cacheLifespan, refreshTime, TimeUnit.MINUTES);
            RemoteJWKSet<SecurityContext> jwkSet = new RemoteJWKSet<>(jwksUrl,null,jwkSetCache);
            jwsKeySelector = JWSAlgorithmFamilyJWSKeySelector.fromJWKSource(jwkSet);
        }
        catch (KeySourceException e) {
            e.printStackTrace();
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
        }

        DefaultJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
        jwtProcessor.setJWSKeySelector(jwsKeySelector);

        return new NimbusJwtDecoder(jwtProcessor);
    }

这篇关于如何在Spring-Security 5.2中增加RemoteJWKSet缓存TTL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆