Я нашел более простой способ:
Мое решение работает для аутентификации по токенам и формирует аутентификацию, но вы можете легко отключить один из них, если хотите.
Мой фильтр похож на фильтр Романа, но мне не нужен чек, если у пользователя есть доступ к определенному ресурсу, а также без выхода из системы -> передано в springSecurity.
Auth фильтр:
public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final String SECURITY_TOKEN_KEY = "token";
private static final String SECURITY_TOKEN_HEADER = "X-Token";
public TokenAuthenticationFilter() {
super("/");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String token = request.getParameter(SECURITY_TOKEN_KEY);
// or this.token = request.getHeader(SECURITY_TOKEN_HEADER);
if (token != null) {
Authentication authResult;
try {
authResult = attemptAuthentication(request, response, token);
if (authResult == null) {
notAuthenticated(request, response, new LockedException("User Not found"));
return;
}
} catch (AuthenticationException failed) {
notAuthenticated(request, response, failed);
return;
}
try {
successfulAuthentication(request, response, chain, authResult);
return;
} catch (NestedServletException e) {
logger.error(e.getMessage(), e);
if (e.getCause() instanceof AccessDeniedException) {
notAuthenticated(request, response, new LockedException("Forbidden"));
return;
}
}
}
chain.doFilter(request, response);// return to others spring security filters
}
public void notAuthenticated(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException {
response.sendRedirect("http://www.google.ro");
// unsuccessfulAuthentication(request, response, failed);
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response, String token) throws AuthenticationException, IOException, ServletException {
AbstractAuthenticationToken userAuthenticationToken = authUserByToken(token);
if (userAuthenticationToken == null)
throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
return userAuthenticationToken;
}
private AbstractAuthenticationToken authUserByToken(String tokenRaw) {
AbstractAuthenticationToken authToken = null;
try {
// check your input token, identify the user
// if success create AbstractAuthenticationToken for user to return
// eg:
// authToken = new UsernamePasswordAuthenticationToken(username, userHash, userAuthorities);
// authToken = new UsernamePasswordAuthenticationToken(tokenRaw, authToken,)
logger.info("token received = " + tokenRaw);
// obtain user by your methods
// if (user != null) {
// SecurityUser securityUser = new SecurityUser(user);
// return new PreAuthenticatedAuthenticationToken(securityUser, securityUser.getPassword(), securityUser.getAuthorities());
// }
} catch (Exception e) {
logger.error("Error during authUserByToken", e);
}
return authToken;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(authResult);
new CustomAuthenticationSuccessHandler().onAuthenticationSuccess(request, response, authResult);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
logger.error("No TOKEN PROVIDED");
return null;
}
}
то все, что вам нужно сделать, чтобы отобразить этот фильтр настраивая его в springSecurity (addFilterBefore), это не должны быть отображены в сервлет конфигурации.
http.authorizeRequests().antMatchers("/login*").permitAll();
http.authorizeRequests().antMatchers("/register*").permitAll();
http.authorizeRequests().antMatchers("/admin/**").hasAnyAuthority("ROLE_ADMIN", "ROLE_USER");//
http.authorizeRequests().and().formLogin()//
.loginPage("/login")//
.successHandler(successHandler())//
.failureUrl("/login?error").permitAll()//
.and().logout()//
.logoutUrl("/logout").logoutSuccessUrl("/login?logout").permitAll()//
.and().rememberMe().key(applicationName + "_key").tokenValiditySeconds(2419200); // remember me for 2 weeks
http.addFilterBefore(new TokenAuthenticationFilter(), AnonymousAuthenticationFilter.class);
Проверьте поддержку OAuth. –