Аутентификация на основе токенов Spring Security
У меня есть rest api, где я аутентифицирую пользователя, используя spring security Basic Authorization, где клиент отправляет имя пользователя и пароль для каждого запроса. Теперь я хочу реализовать аутентификацию на основе токенов, при которой я буду отправлять токен в заголовке ответа, когда пользователь аутентифицируется в первый раз. При последующих запросах клиент может включить этот токен в заголовок, который будет использоваться для аутентификации пользователя к ресурсам. У меня есть два провайдера аутентификации tokenAuthenticationProvider и daoAuthenticationProvider
@Component
public class TokenAuthenticationProvider implements AuthenticationProvider {
@Autowired
private TokenAuthentcationService service;
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
final HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
final String token = request.getHeader(Constants.AUTH_HEADER_NAME);
final Token tokenObj = this.service.getToken(token);
final AuthenticationToken authToken = new AuthenticationToken(tokenObj);
return authToken;
}
@Override
public boolean supports(final Class<?> authentication) {
return AuthenticationToken.class.isAssignableFrom(authentication);
}
}
И в daoAuthenticationProvider я устанавливаю пользовательский userDetailsService и аутентифицирую пользователя по его регистрационным данным, получая их из базы данных (что работает нормально, пока имя пользователя и пароль передаются с использованием Authorization:Basic bGllQXBpVXNlcjogN21wXidMQjRdTURtR04pag== в качестве заголовка).
Но когда я включаю токен в заголовок, используя X-AUTH-TOKEN (который является Constants.AUTH_HEADER_NAME), tokenAuthenticationProvider не вызывается. Я получаю ошибку следующего вида
{"timestamp":1487626368308,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/find"}
А вот как я добавляю провайдеров аутентификации.
@Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
final UsernamePasswordAuthenticationProvider daoProvider = new
UsernamePasswordAuthenticationProvider(this.service, this.passwordEncoder());
auth.authenticationProvider(this.tokenAuthenticationProvider);
auth.authenticationProvider(daoProvider);
}
Пожалуйста, подскажите, как я могу реализовать аутентификацию на основе токенов без ущерба для текущего поведения spring security.
Вот как я смог реализовать аутентификацию на основе маркера и базовую аутентификацию
SpringSecurityConfig.java
TokenAuthenticationFilter.java
CustomBasicAuthenticationFilter.java
Поскольку наш CustomBasicAuthenticationFilter был настроен и добавлен как фильтр в spring security,
При успешной базовой аутентификации запрос будет перенаправлен на onSuccessfulAuthentication, где мы установим токен и отправим его в ответ с некоторым заголовком "header-name".
Если "заголовок-имя" отправлен для дальнейшего запроса, то запрос сначала пройдет через TokenAuthenticationFilter перед попыткой базовой аутентификации.
Вы можете попробовать установить ваш собственный токен
AuthenticationToken
в вашем фильтре аутентификации, например: