Как увеличить TTL кеша RemoteJWKSet в Spring-Security 5.2 - PullRequest
3 голосов
/ 26 февраля 2020

Мы используем spring-security 5.2 для защиты нашего REST API посредством проверки JWT.

С помощью свойства spring:security:oauth2:resourceserver:jwt:jwk-set-uri мы указываем удаленную конечную точку JWKS, которая преобразуется в Spring, создавая NimbusJwtDecoder на основе этого URI. Далее создается объект RemoteJWKSet, который кэширует вызовы конечной точки JWKS с TTL по умолчанию до 5 минут.

Есть ли способ увеличить этот TTL для минимизации удаленных вызовов? Может быть, внедрить новый экземпляр DefaultJWKSetCache где-нибудь с другим TTL? Кажется безопасным хранить это в кеше как можно дольше, потому что, когда мы получим токен с неизвестным ребенком, вызов к конечной точке JWKS будет возобновлен для обновления набора ключей.

Стек вызова для получения ключа приведен ниже

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
...