目录

一、JWT的最小依赖

二、JWT的最基本配置

1、指定授权服务器

2、初始预期(Startup Expectations)

3、运行时预期(Runtime Expectations)


大多数资源服务器支持收集springsecurity-oauth2-resourceserver 中。然而,对JWT的解码验证支持是在 springsecurity-oauth2-jose 中,这意味着为了拥有一个支持JWT编码的 Bearer Token 的工作资源服务器,两者都是必要的。

使用 Spring Boot 时,将一个应用程序配置资源服务器包括两个基本步骤。首先,包括所需的依赖,其次,指定授权服务器位置

在Spring Boot应用程序中,要指定使用一个授权服务器,只需:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com/issuer

其中 idp.example.com/issuer,是授权服务器将发出的JWT令牌的 iss claim包含的值。资源服务器将使用这个属性来进一步自我配置发现授权服务器的公钥,并随后验证传入的 JWT。

使用 issuer-uri 属性,还必须是 idp.example.com/issuer/.well-known/openidconfiguration、idp.example.com/.well-known/openidconfiguration/issuer 或 idp.example.com/.well-known/oauthauthorization-server/issuer 中的一个是授权服务器的支持端点。这个端点被称为 提供者配置 端点或 授权服务器元数据 端点。

就这样!

使用属性和这些依赖关系时,资源服务器将自动配置自己以验证JWT编码的Bearer Token。

它通过一个确定性的启动过程实现这一点。

  1. 查询提供者配置或授权服务器元数据端点的 jwks_url 属性
  2. 查询 jwks_url 端点的支持算法
  3. 配置验证策略,以查询 jwks_url 中找到的算法的有效公钥
  4. 配置验证策略,根据 idp.example.com验证每个JWTs iss claim

这个过程的一个结果是,授权服务器必须启动接收请求以便资源服务器成功启动

如果在资源服务查询时,授权服务器已经停机(给定适当的超时),那么启动将失败

一旦应用程序启动,资源服务器将尝试处理任何包含 Authorization: Bearer 头的请求

GET / HTTP/1.1
Authorization: Bearer some-token-value # Resource Server will process this

只要指定了这个 scheme,资源服务器就会尝试根据 Bearer Token 规范处理请求

给定一个格式良好的JWT,资源服务器将:

  1. 根据启动期间从 jwks_url 端点获得的公钥验证签名,并与JWT相匹配
  2. 验证JWT的 exp 和 nbf 时间戳以及JWT的 iss claim
  3. 每个 scope 映射到一个前缀为 SCOPE_ 的授权。

随着授权服务器提供新的密钥,Spring Security将自动轮换用于验证JWTs的密钥

由此产生的 Authentication#getPrincipal 默认为Spring Security Jwt 对象,Authentication#getName 映射到JWT的 sub 属性,如果有的话。

这里,考虑跳转到:

接下来,让我们看看Spring Security用来支持基于servlet的应用程序中的 JWT 认证架构组件比如我们刚才看到的那个。

JwtAuthenticationProvider 是一个 AuthenticationProvider 实现,利用 JwtDecoder 和 JwtAuthenticationConverter 来验证JWT。

我们看看 JwtAuthenticationProvider 是如何在Spring Security中工作的。图中解释了数字中的 AuthenticationManager 在 读取 Bearer Token时的工作细节

Figure 1. JwtAuthenticationProvider Usage

读取 Bearer Token 的认证 Filter 将一个 BearerTokenAuthenticationToken 传递给由 ProviderManager 实现的认证管理器

ProviderManager 被配置为使用一个 JwtAuthenticationProvider 类型的 AuthenticationProvider。

JwtAuthenticationProvider 使用 JwtDecoder 对 Jwt 进行解码、验证和确认。

JwtAuthenticationProvider 然后使用 JwtAuthenticationConverter 将 Jwt 转换为授予权限集合(Collection )。

当认证成功时,返回的 Authentication 是 JwtAuthenticationToken 类型的,并且有一个 principal 是由配置的 JwtDecoder 返回的 Jwt。最终,返回的 JwtAuthenticationToken 将被认证 Filter 设置在 SecurityContextHolder 上。

如果授权服务器不支持任何配置端点,或者如果资源服务器必须能够独立于授权服务器启动,那么也可以提供 jwkset-uri。

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com
          jwk-set-uri: https://idp.example.com/.well-known/jwks.json

JWK Set uri不是标准化的,但通常可以在授权服务器的文档中找到。

因此,资源服务器在启动时将不会ping授权服务器。我们仍然指定了 issuer-uri,这样资源服务器仍然会验证传入的JWT的 iss claim

This property can also be supplied directly on the DSL.

如前所述,issuer-uri 属性验证了 iss claim;这是谁发送的JWT。

Boot 还具有用于验证 aud claim 的 audiences 属性;这是 JWT 的发送对象

资源服务器的 audience 可以这样表示:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com
          audiences: https://my-resource-server.example.com

如果需要,你也可以 通过编程添加 aud 验证。

结果是,如果 JWT 的 iss claim 不是 idp.example.com,且其 aud claim 的列表中不包含 myresource-server.example.com,则验证将失败

有两个 @Bean 是Spring Boot代表资源服务器生成的。

第一个是 SecurityFilterChain,它将应用程序配置为资源服务器。当包括 springsecurity-oauth2-jose 时,这个 SecurityFilterChain 看起来像:

Default JWT Configuration

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(authorize -> authorize
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
    return http.build();
}

如果应用程序没有公开 SecurityFilterChain Bean,那么Spring Boot将公开上述的默认bean

替换它就像在应用程序中公开该bean一样简单

Custom JWT Configuration

@Configuration
@EnableWebSecurity
public class MyCustomSecurityConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/messages/**").hasAuthority("SCOPE_message:read")
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    .jwtAuthenticationConverter(myConverter())
                )
            );
        return http.build();
    }
}

以上要求任何以 /messages/ 开头的URL的scopemessage:read

oauth2ResourceServer DSL上的方法也将覆盖或取代自动配置。

例如,Spring Boot 创建第二个 @Bean 是一个 JwtDecoder,它 将 String token 解码为 Jwt 的验证实例

JWT Decoder

@Bean
public JwtDecoder jwtDecoder() {
    return JwtDecoders.fromIssuerLocation(issuerUri);
}

调用 JwtDecoders#fromIssuerLocation 就是调用提供者配置或授权服务器元数据端点,以便导出JWK Set Uri。

如果应用程序没有暴露一个 JwtDecoder Bean,那么Spring Boot将暴露上述默认的 JwtDecoder。

它的配置可以用 jwkSetUri() 重写或用 decoder() 替换

或者,如果你根本没有使用Spring Boot,那么这两个组件—​filter chain 和 JwtDecoder 都可以用XML指定

过滤器链(filter chain)是这样指定的。

Default JWT Configuration

<http>
    <intercept-uri pattern="/**" access="authenticated"/>
    <oauth2-resource-server>
        <jwt decoder-ref="jwtDecoder"/>
    </oauth2-resource-server>
</http>

而 JwtDecoder 是这样的:

JWT Decoder

  • Java
<bean id="jwtDecoder"
        class="org.springframework.security.oauth2.jwt.JwtDecoders"
        factory-method="fromIssuerLocation">
    <constructor-arg value="${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}"/>
</bean>

授权服务器的 JWK Set Uri 可以 作为一个配置属性 来配置,也可以在DSL中提供。

JWK Set Uri Configuration

  • Java
@Configuration
@EnableWebSecurity
public class DirectlyConfiguredJwkSetUri {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    .jwkSetUri("https://idp.example.com/.well-known/jwks.json")
                )
            );
        return http.build();
    }
}

使用 jwkSetUri() 优先于任何配置属性

比 jwkSetUri() 更强大的是 decoder(),它将完全取代 JwtDecoder 的任何Boot自动配置。

JWT Decoder Configuration

  • Java
@Configuration
@EnableWebSecurity
public class DirectlyConfiguredJwtDecoder {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    .decoder(myCustomDecoder())
                )
            );
        return http.build();
    }
}

需要更深入的配置时,如 validationmappingrequest timeouts,这很方便。

或者,暴露一个JwtDecoder @Bean 与 decoder() 有同样的效果

你可以像这样用 jwkSetUri 构建一个:

  • Java
@Bean
public JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
}

或者你可以使用 issuer,并让 NimbusJwtDecoder 在调用 build() 时查找 jwkSetUri,如下所示

  • Java
@Bean
public JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withIssuerLocation(issuer).build();
}

或者,如果默认值对你有效,你也可以使用 JwtDecoders,除了配置 decoder 的验证器之外,它还可以完成上述工作

  • Java
@Bean
public JwtDecoders jwtDecoder() {
    return JwtDecoders.fromIssuerLocation(issuer);
}

默认情况下,NimbusJwtDecoder,以及资源服务器,将只信任和验证使用 RS256 的令牌。

你可以通过Spring Boot、NimbusJwtDecoder builder或从 JWK Set response定制

设置算法的最简单方法是配置一个属性。

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jws-algorithm: RS512
          jwk-set-uri: https://idp.example.org/.well-known/jwks.json

不过,为了获得更大的权力,我们可以使用 NimbusJwtDecoder 附带的一个构建器。

  • Java
@Bean
JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withIssuerLocation(this.issuer)
            .jwsAlgorithm(RS512).build();
}

多次调用 jwsAlgorithm 将配置 NimbusJwtDecoder 以信任一种以上的算法,像这样。

  • Java
@Bean
JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withIssuerLocation(this.issuer)
            .jwsAlgorithm(RS512).jwsAlgorithm(ES512).build();
}

或者,你可以调用 jwsAlgorithms

  • Java
@Bean
JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withIssuerLocation(this.issuer)
            .jwsAlgorithms(algorithms -> {
                    algorithms.add(RS512);
                    algorithms.add(ES512);
            }).build();
}

由于 Spring Security 的 JWT 支持基于 Nimbus,因此你也可以使用它的所有强大功能

例如,Nimbus有一个 JWSKeySelector 实现,它将根据JWK Set URI的响应(Response)来选择算法集。你可以用它来生成一个 NimbusJwtDecoder,像这样。

  • Java
@Bean
public JwtDecoder jwtDecoder() {
    // makes a request to the JWK Set endpoint
    JWSKeySelector<SecurityContext> jwsKeySelector =
            JWSAlgorithmFamilyJWSKeySelector.fromJWKSetURL(this.jwkSetUrl);

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

    return new NimbusJwtDecoder(jwtProcessor);
}

比用JWK Set端点支持资源服务器更简单的是硬编码一个RSA公钥公钥可以通过Spring Boot或 使用 Builder来提供。

通过Spring Boot指定一个密钥是非常简单的。密钥的位置可以像这样指定。

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          public-key-location: classpath:my-key.pub

或者,为了能够进行更复杂的查询,你可以用 RsaKeyConversionServicePostProcessor 进行后处理

  • Java
@Bean
BeanFactoryPostProcessor conversionServiceCustomizer() {
    return beanFactory ->
        beanFactory.getBean(RsaKeyConversionServicePostProcessor.class)
                .setResourceLoader(new CustomResourceLoader());
}

指定你的key的位置。

key.location: hfds://my-key.pub

然后自动注入value

  • Java
@Value("${key.location}")
RSAPublicKey key;

2、使用 Builder

要直接连接一个 RSAPublicKey,你可以简单地使用适当的 NimbusJwtDecoder builder,像这样。

  • Java
@Bean
public JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withPublicKey(this.key).build();
}

使用单一的对称密钥也很简单。你可以简单地加载你的 SecretKey 并使用适当的 NimbusJwtDecoder builder,像这样。

  • Java
@Bean
public JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withSecretKey(this.key).build();
}

从OAuth 2.0授权服务器发出的JWT通常会有一个 scopescp 属性,表明它被授予的scope(或权限),例如:

{ …​, “scope” : “messages contacts“}

当出现这种情况时,资源服务器将尝试把这些scope强制性的成一个授予权限的列表,在每个scope前面加上 “SCOPE_” 字符串

这意味着,要用从JWT派生的scope保护一个端点或方法,相应的表达式应该包括这个前缀

Authorization Configuration

  • Java
@Configuration
@EnableWebSecurity
public class DirectlyConfiguredJwkSetUri {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/contacts/**").hasAuthority("SCOPE_contacts")
                .requestMatchers("/messages/**").hasAuthority("SCOPE_messages")
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
        return http.build();
    }
}

或者类似于方法安全(method security)。

  • Java
@PreAuthorize("hasAuthority('SCOPE_messages')")
public List<Message> getMessages(...) {}

然而,在很多情况下,这个默认值是不够的。例如,有些授权服务器并不使用 scope 属性,而是有自己的自定义属性。或者,在其他时候,资源服务器可能需要将属性或属性的构成调整为内部化的授权。

为此,Spring Security提供了 JwtAuthenticationConverter,它负责 将 Jwt 转换为 Authentication。默认情况下,Spring Security会将 JwtAuthenticationProvider 与 JwtAuthenticationConverter 的默认实例连接起来。

作为配置 JwtAuthenticationConverter 的一部分,你可以提供一个附属的转换器,从 Jwt 到授予权限集合(Collection)。

假设你的授权服务器在一个名为 authorities 的自定义 claim 中交流授权。在这种情况下,你可以配置 JwtAuthenticationConverter 应该检查的 claim,像这样。

Authorities Claim Configuration

  • Java
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
    grantedAuthoritiesConverter.setAuthoritiesClaimName("authorities");

    JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
    jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
    return jwtAuthenticationConverter;
}

你也可以把权限的前缀配置成不同的。你可以像这样把每个权限的前缀改为 ROLE_,而不是用 SCOPE_。

Authorities Prefix Configuration

  • Java
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
    grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");

    JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
    jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
    return jwtAuthenticationConverter;
}

或者,你可以通过调用 JwtGrantedAuthoritiesConverter#setAuthorityPrefix(“”) 完全删除前缀

为了提高灵活性,DSL支持用任何实现 Converter<Jwt, AbstractAuthenticationToken> 的类来完全替换converter。

  • Java
static class CustomAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
    public AbstractAuthenticationToken convert(Jwt jwt) {
        return new CustomAuthenticationToken(jwt);
    }
}

// ...

@Configuration
@EnableWebSecurity
public class CustomAuthenticationConverterConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    .jwtAuthenticationConverter(new CustomAuthenticationConverter())
                )
            );
        return http.build();
    }
}

使用 最小的Spring Boot配置,表明授权服务器的发行者URI,资源服务器将默认验证 iss claim 以及 exp 和 nbf 时间戳 claim。

需要定制验证的情况下,资源服务器会提供两个标准的验证器,同时也接受自定义的 OAuth2TokenValidator 实例

JWT通常有一个有效期,开始时间在 nbf claim 中指出,结束时间exp 声明中指出。

然而,每台服务器都可能经历时钟漂移,这可能导致令牌在一台服务器上显示为过期,而在另一台服务器上却不是。随着分布式系统合作服务器数量的增加,这可能会造成一些实施上的困扰。

资源服务器使用 JwtTimestampValidator 来验证令牌的有效性,它可以配置一个 clockSkew 来缓解上述问题

  • Java
@Bean
JwtDecoder jwtDecoder() {
     NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
             JwtDecoders.fromIssuerLocation(issuerUri);

     OAuth2TokenValidator<Jwt> withClockSkew = new DelegatingOAuth2TokenValidator<>(
            new JwtTimestampValidator(Duration.ofSeconds(60)),
            new JwtIssuerValidator(issuerUri));

     jwtDecoder.setJwtValidator(withClockSkew);

     return jwtDecoder;
}

默认情况下,资源服务器配置的时钟偏移为60秒。

使用 OAuth2TokenValidator API,添加 aud claim 的检查很简单。

  • Java
  • Kotlin
OAuth2TokenValidator<Jwt> audienceValidator() {
    return new JwtClaimValidator<List<String>>(AUD, aud -> aud.contains("messaging"));
}

或者,为了更多的控制,你可以实现你自己的 OAuth2TokenValidator。

  • Java
static class AudienceValidator implements OAuth2TokenValidator<Jwt> {
    OAuth2Error error = new OAuth2Error("custom_code", "Custom error message", null);

    @Override
    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        if (jwt.getAudience().contains("messaging")) {
            return OAuth2TokenValidatorResult.success();
        } else {
            return OAuth2TokenValidatorResult.failure(error);
        }
    }
}

// ...

OAuth2TokenValidator<Jwt> audienceValidator() {
    return new AudienceValidator();
}

然后,为了添加到资源服务器中,只需指定 JwtDecoder 实例即可

  • Java
@Bean
JwtDecoder jwtDecoder() {
    NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
        JwtDecoders.fromIssuerLocation(issuerUri);

    OAuth2TokenValidator<Jwt> audienceValidator = audienceValidator();
    OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
    OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);

    jwtDecoder.setJwtValidator(withAudience);

    return jwtDecoder;
}

如前所述,你可以在 Boot 中 配置 aud 验证。

Spring Security使用 Nimbus 库来解析JWT并验证其签名。因此,Spring Security受制于Nimbus对每个字段值的解释,以及如何将每个字段强制成一个Java类型

例如,由于Nimbus仍然与Java 7兼容,它不使用 Instant 来表示时间字段

而且,完全可以使用不同的库或用于JWT处理,它可能会做出自己的强制决定,需要进行调整。

或者,很简单,资源服务器可能想出于特定领域的原因从JWT中添加或删除claim。

为了这些目的,资源服务器支持用 MappedJwtClaimSetConverter 映射JWT请求集。

默认情况下,MappedJwtClaimSetConverter 将试图将 claim 强制为以下类型

Claim

Java 类型

aud

Collection<String>

exp

Instant

iat

Instant

iss

String

jti

String

nbf

Instant

sub

String

可以使用 MappedJwtClaimSetConverter.withDefaults 来配置单个 claim 的转换策略

  • Java
@Bean
JwtDecoder jwtDecoder() {
    NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(issuer).build();

    MappedJwtClaimSetConverter converter = MappedJwtClaimSetConverter
            .withDefaults(Collections.singletonMap("sub", this::lookupUserIdBySub));
    jwtDecoder.setClaimSetConverter(converter);

    return jwtDecoder;
}

这将保持所有的默认值,除了它将覆盖 sub 的默认 claim converter。

MappedJwtClaimSetConverter 也可以用来添加一个自定义的 claim,例如,为了适应现有的系统

  • Java
MappedJwtClaimSetConverter.withDefaults(Collections.singletonMap("custom", custom -> "value"));

删除claim也很简单,使用相同的API。

  • Java
MappedJwtClaimSetConverter.withDefaults(Collections.singletonMap("legacyclaim", legacy -> null));

在更复杂的情况下,如同时咨询多个claim或重命名一个claim,资源服务器接受任何实现 Converter<Map<String, Object>, Map<String,Object>> 的类。

  • Java
public class UsernameSubClaimAdapter implements Converter<Map<String, Object>, Map<String, Object>> {
    private final MappedJwtClaimSetConverter delegate =
            MappedJwtClaimSetConverter.withDefaults(Collections.emptyMap());

    public Map<String, Object> convert(Map<String, Object> claims) {
        Map<String, Object> convertedClaims = this.delegate.convert(claims);

        String username = (String) convertedClaims.get("user_name");
        convertedClaims.put("sub", username);

        return convertedClaims;
    }
}

然后,可以像正常一样提供实例

  • Java
@Bean
JwtDecoder jwtDecoder() {
    NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(issuer).build();
    jwtDecoder.setClaimSetConverter(new UsernameSubClaimAdapter());
    return jwtDecoder;
}

默认情况下,资源服务器使用连接和套接字超时30秒来与授权服务器进行协调。

这在某些情况下可能太短了。此外,它没有考虑到更复杂的模式,如退订和发现。

为了调整资源服务器连接到授权服务器的方式,NimbusJwtDecoder 接受了一个 RestOperations 的实例

  • Java
@Bean
public JwtDecoder jwtDecoder(RestTemplateBuilder builder) {
    RestOperations rest = builder
            .setConnectTimeout(Duration.ofSeconds(60))
            .setReadTimeout(Duration.ofSeconds(60))
            .build();

    NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withIssuerLocation(issuer).restOperations(rest).build();
    return jwtDecoder;
}

另外,默认情况下,资源服务器会在内存缓存授权服务器的JWK集5分钟,你可能想调整一下。此外,它没有考虑到更复杂的缓存模式,如驱逐或使用共享缓存

为了调整资源服务器缓存JWK集的方式,NimbusJwtDecoder 接受一个 Cache 的实例

  • Java
@Bean
public JwtDecoder jwtDecoder(CacheManager cacheManager) {
    return NimbusJwtDecoder.withIssuerLocation(issuer)
            .cache(cacheManager.getCache("jwks"))
            .build();
}

给定一个 Cache 时,资源服务器将使用JWK Set Uri作为键,JWK Set JSON作为值。

Spring不是一个缓存提供者,所以你需要确保包含适当的依赖关系,比如 springbootstarter-cache 和你喜欢的缓存提供者。

无论是套接字还是缓存超时,你可能反而想直接与Nimbus合作。要做到这一点,请记住 NimbusJwtDecoder 有一个构造函数,它接收 Nimbus 的 JWTProcessor。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注