在spring boot中设置`security.oauth2.resource.jwk.key-set-uri`时的预期行为是什么

Aly*_*him 7 spring-boot

在 Spring Boot 中,在配置资源服务器时,我们可以选择设置security.oauth2.resource.jwk.key-set-uri属性,如果访问令牌将是 JWT,并且颁发者为客户端提供端点以获取公共 RSA 密钥以进行 JWK 格式的验证。

从此 JWK 启动密钥库的预期行为是什么?该属性正在加载,ResourceServerProperties.JWK但是然后呢。spring boot 应该调用这个 URI 并获取 jwks 然后创建一个商店供我在验证中使用吗?

我正在按照本教程设置密钥库http://www.baeldung.com/spring-security-oauth-jwt的配置

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        Resource resource = new ClassPathResource("public.txt");
        String publicKey = null;
        try {
            publicKey = IOUtils.toString(resource.getInputStream());
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
        converter.setVerifierKey(publicKey);
        return converter;
    }
Run Code Online (Sandbox Code Playgroud)

但是.pem我想我想从jwk.

Sim*_*ngh 5

如果你想使用JWKS,使用JwkTokenStore到位JwtTokenStore

spring-security-oauth2/jwk内部根据auth0规范实现key加载和管理

您还可以查看有关相同自动配置的文档,但是我觉得配置它非常简单(见下文)。

我们不必进行任何验证,因为JwkTokenStore使用JwkDefinitionSource JwkVerifyingJwtAccessTokenConverter使用公开的JWKS设置验证@Value("{jsecurity.oauth2.resource.jwk.key-set-uri}")

但是,spring 的 spring-security-oauth2/jwk类没有任何公共构造函数,我们经常需要并且可以在 AccessTokenConversion 中执行任何自定义步骤,就像一个常见的需求是将 jwt 内容提取到 auth 上下文中,我们可以随时注入JwkTokenStore的自定义转换器

import org.springframework.security.oauth2.provider.token.store.jwk.*;
import org.springframework.security.oauth2.provider.token.store.*
import org.springframework.security.oauth2.provider.token.*;
import java.utl.*;

@Configuration
class JwtConfiguration {

  @Bean
  public DefaultTokenServices tokenServices(final TokenStore tokenStore) {
    final DefaultTokenServices dts = new DefaultTokenServices();
    dts.setTokenStore(tokenStore);
    dts.setSupportRefreshToken(true);
    return dts;
  }

  @Bean
  public TokenStore tokenStore( 
    @Value("{jsecurity.oauth2.resource.jwk.key-set-uri}") final String jwksUrl,
    final JwtAccessTokenConverter jwtAccessTokenConverter) {
    return new  JwkTokenStore(jwksUrl, jwtAccessTokenConverter, null);
  }

  @Bean
  public JwtAccessTokenConverter createJwtAccessTokenConverter() {
    final JwtAccessTokenConverter converter;   
    converter.setAccessTokenConverter(new  DefaultAccessTokenConverter() {
      @Override
      public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
        final OAuth2Authentication auth = super.extractAuthentication(map);
        auth.setDetails(map); //this will get spring to copy JWT content into 
        return auth;
        }

      }
    return conveter;
  }
Run Code Online (Sandbox Code Playgroud)
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
@Configuration
@EnableResourceServer
class ResourceServerConfig extends ResourceServerConfigurerAdapter {

  private String resourceId;
  private TokenStore tokenStore;

  public ResourceServerConfig(
    @Value("\${jwt.reourceId}") private String resourceId,
    private TokenStore tokenStore) {
           this.resourceId = resourceId;
           this.tokenStore = tokenStore;
  }

  /**
  * Ensures request to all endpoints ore a
  @Override 
  public void configure(final HttpSecurity http) {
    http.csrf().disable()
     .authorizeRequests()
     .antMatchers("/**").authenticated();
  }

  /**
  * Configure resources
  * Spring OAuth expects "aud" claim in JWT token. That claim's value should match to the resourceId value
  * (if not specified it defaults to "oauth2-resource").
  */
   @Override 
   public void configure(final ResourceServerSecurityConfigurer resources) {
     resources.resourceId(resourceId).tokenStore(tokenStore);
   }
}
Run Code Online (Sandbox Code Playgroud)


Pan*_*arn 3

此实现的主要目标是使用相应的 JWK(JSON WEB TOKEN KEY SET)在本地验证 JWT。用于验证的JWK是使用JWT的kid头参数和JWK的kid属性来匹配的。

服务器可以在本地验证此令牌,而无需发出任何网络请求、与数据库通信等。这可能会使会话管理更快,因为您不需要在每个请求上从数据库(或缓存)加载用户,而只需要运行一小部分本地代码。这可能是人们喜欢使用 JWT 的最大原因:它们是无状态的。