Spring Boot + JWT:应该根据身份验证服务器检查令牌

时间:2019-03-24 16:08:44

标签: spring-boot spring-security jwt

据我了解,JWT包含标头,有效负载和签名。

签名通过使用机密对标头和有效负载进行加密来确保JWT完整性。

因此,如果身份验证(令牌)服务器和资源服务器共享同一秘密,则资源服务器应该能够自己验证令牌,这就是这些令牌的目的。

因此,我有两个问题:

  • Spring为什么提供RemoteTokenServices,不是反模式吗?

[EDIT]自己回答了这个问题:

  

实际上,使用JWT而不对令牌存储进行检查的主要问题是我们无法撤销它们。仅使用签名来检查其真实性,任何令牌都将保持有效,直到过期。

     

对照令牌存储检查JWT可以撤消令牌,在这种情况下,已被撤消的有效JWT将不被接受来验证请求。

     

因此,使用自我认证的JWT唯一安全的方法是到期时间非常短。

  • 如果我不使用此服务,如何仅使用秘密在本地实现令牌验证?

我当前咨询远程令牌服务的资源服务器的配置:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Profile("!test")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Value("${auth-server.url}")
    private String authEndpoint;

    @Value("${security.oauth2.client.client-id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;

    @Override
  public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId("ms/legacy");
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().permitAll().and().cors().disable().csrf().disable().httpBasic().disable()
        .exceptionHandling()
        .authenticationEntryPoint(
            (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
        .accessDeniedHandler(
            (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED));
  }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("ms/legacy");
    }

    @Bean
    public ResourceServerTokenServices tokenService() {
        RemoteTokenServices tokenServices = new RemoteTokenServices();
        tokenServices.setClientId(clientId);
        tokenServices.setClientSecret(clientSecret);
        tokenServices.setCheckTokenEndpointUrl(authEndpoint + "/uaa/oauth/check_token");
        return tokenServices;
    }
}

1 个答案:

答案 0 :(得分:1)

  
      
  • 为什么Spring提供了RemoteTokenServices,这不是一种反模式吗?
  •   

Spring是一个灵活的框架,将为您提供不同的实现  ,它使您可以选择最适合您需求的最佳实施方式

  
      
  • 如果我不使用此服务,如何仅使用秘密在本地实现令牌验证?
  •   

本地令牌验证:

    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {   

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.tokenServices(tokenServices());
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        return converter;
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }
    }