Как я понимаю, 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;
}
}