Points To Remember
You may need to create an AuthenticatioFilter when you want to create a custom logic for handling the authentication filter. You may also want to create your own Authentication Provider, Entry Point, Authentication Token etc to customize the authentication process to a new level.Step 1 : Create a Filter
Let us first create a class named MyAuthenticationFilter and then register it as a bean in resources.groovy. After we have created the class and registered the it as a bean, we can use this class as a filter for our custom spring security authentication.Class : MyAuthenticationFilter.groovy
package com.ekiras
import org.springframework.context.ApplicationEventPublisher
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
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.AuthenticationSuccessHandler
import javax.servlet.FilterChain
import javax.servlet.ServletException
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
/**
* Created by ekansh on 19/1/15.
*/
class MyAuthenticationFilter extends AbstractAuthenticationProcessingFilter{
public static final String USERNAME = 'j_username';
public static final String PASSWORD = 'j_password';
AuthenticationSuccessHandler authenticationSuccessHandler
AuthenticationFailureHandler authenticationFailureHandler
ApplicationEventPublisher applicationEventPublisher
protected MyAuthenticationFilter() {
super('/mylogin') // Register the url that will be intercepted by this filter.
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req
HttpServletResponse response = (HttpServletResponse) resp
//Check if the url contains the filterProcessUrl and required authentication is false, if not then pass the request to the next filter.
if (!request.getRequestURI().contains(filterProcessesUrl) && !requiresAuthentication(request, response)) {
chain.doFilter(request, response)
return
}
// Create an authentication token that will be returned.
Authentication authentication;
try{ // If the credentials to not match then an AuthenticationException is thrown.
authentication = attemptAuthentication(request, response)
// If successfully authenticated then pass the request to the success handler
if(authentication.authenticated)
successfulAuthentication(request,response,authentication)
}
catch(AuthenticationException exception){
// Pass the request to authentication failure handler.
unsuccessfulAuthentication(request,response,exception)
return
}
}
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return true;
}
@Override
Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
String username = getUsername(httpServletRequest);
String password = getPassword(httpServletRequest);
Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);
return this.authenticationManager.authenticate(authentication);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException{
SecurityContextHolder.getContext().setAuthentication(authentication)
applicationEventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authentication, this.class))
authenticationSuccessHandler.onAuthenticationSuccess(request,response,authentication)
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException{
authenticationFailureHandler.onAuthenticationFailure(request,response, exception)
}
// Get the username from the request object
String getUsername(HttpServletRequest request){
return request.getParameter(USERNAME);
}
// get the password from the request object
String getPassword(HttpServletRequest request){
return request.getParameter(PASSWORD);
}
}
myAuthenticationFilter(MyAuthenticationFilter){
authenticationManager = ref('authenticationManager')
sessionAuthenticationStrategy = ref('sessionAuthenticationStrategy')
authenticationSuccessHandler = ref('authenticationSuccessHandler')
authenticationFailureHandler = ref('authenticationFailureHandler')
rememberMeServices = ref('rememberMeServices')
authenticationDetailsSource = ref('authenticationDetailsSource')
filterProcessesUrl = '/mylogin'
}
Now you need to register this filter in the deployment descriptor so that the these effects take place. There are two ways of doing this
- You can declare your filter using a filter chain in Config.groovy. See the documentation how to do this.
- You can declare the filter in bootsrap as following
SpringSecurityUtils.clientRegisterFilter('myAuthenticationFilter', SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order + 10)
Comments
Post a Comment