package org.dicadeveloper.weplantaforest.security; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.dicadeveloper.weplantaforest.user.User; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.NullRememberMeServices; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import com.fasterxml.jackson.databind.ObjectMapper; public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter { private final TokenAuthenticationService tokenAuthenticationService; private final UserDetailsService userDetailsService; private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler(); private RememberMeServices rememberMeServices = new NullRememberMeServices(); public StatelessLoginFilter(String urlMapping, TokenAuthenticationService tokenAuthenticationService, UserDetailsService userDetailsService, AuthenticationManager authManager) { super(new AntPathRequestMatcher(urlMapping)); this.userDetailsService = userDetailsService; this.tokenAuthenticationService = tokenAuthenticationService; setAuthenticationManager(authManager); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { final User user = new ObjectMapper().readValue(request.getInputStream(), User.class); final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()); return getAuthenticationManager().authenticate(loginToken); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException { // Lookup the complete User object from the database and create an // Authentication for it final User authenticatedUser = userDetailsService.loadUserByUsername(authentication.getName()); final UserAuthentication userAuthentication = new UserAuthentication(authenticatedUser); // Add the custom token as HTTP header to the response tokenAuthenticationService.addAuthentication(response, userAuthentication); // Add the authentication to the Security context SecurityContextHolder.getContext() .setAuthentication(userAuthentication); } @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { SecurityContextHolder.clearContext(); if (logger.isDebugEnabled()) { logger.debug("Authentication request failed: " + failed.toString()); logger.debug("Updated SecurityContextHolder to contain null Authentication"); logger.debug("Delegating to authentication failure handler " + failureHandler); } rememberMeServices.loginFail(request, response); failureHandler.onAuthenticationFailure(request, response, failed); } }