Spring Boot + JWT: нужно проверять токены на сервере аутентификации - PullRequest
0 голосов
/ 24 марта 2019

Как я понимаю, 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 Ответ

1 голос
/ 24 марта 2019
  • почему 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;
    }
    }
...