Skip to content

Instantly share code, notes, and snippets.

@theresajayne
Created October 10, 2011 07:40
Show Gist options
  • Save theresajayne/1274810 to your computer and use it in GitHub Desktop.
Save theresajayne/1274810 to your computer and use it in GitHub Desktop.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package uk.co.inbrand.testproject;
import java.io.IOException;
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;
import javax.servlet.http.HttpSession;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.TextEscapeUtils;
import org.springframework.util.Assert;
/**
* This class should override the default login j_spring_security_check call and
* process the pre login "change password" tickbox as requested by Chris
*
* @author Theresa
*/
public class LoginFilter extends AbstractAuthenticationProcessingFilter{
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
public static final String SPRING_SECURITY_FORM_CHANGE_PASSWORD = "j_changepassword";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private String changePasswordParameter = SPRING_SECURITY_FORM_CHANGE_PASSWORD;
private boolean postOnly = true;
private static final String DEFAULT_FILTER_PROCESSES_URL="/login";
private static final String POST="POST";
protected LoginFilter() {
super(DEFAULT_FILTER_PROCESSES_URL);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (postOnly && !request.getMethod().equals(POST)) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
String changePassword = obtainChangePassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
if(changePassword == null) {
changePassword="FALSE";
} else if (changePassword.compareTo("checked")==0) {
changePassword="TRUE";
} else {
changePassword="FALSE";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Place the last username attempted into HttpSession for views
HttpSession session = request.getSession(false);
if (session != null || getAllowSessionCreation()) {
request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
request.getSession().setAttribute(SPRING_SECURITY_FORM_CHANGE_PASSWORD, changePassword);
}
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
if(request.getMethod().equals(POST)) {
// If the incoming request is a POST, then we send it up
// to the AbstractAuthenticationProcessingFilter.
super.doFilter(request, response, chain);
} else {
// If it's a GET, we ignore this request and send it
// to the next filter in the chain. In this case, that
// pretty much means the request will hit the /login
// controller which will process the request to show the
// login page.
chain.doFilter(request, response);
}
}
/**
* Enables subclasses to override the composition of the password, such as by including additional values
* and a separator.<p>This might be used for example if a postcode/zipcode was required in addition to the
* password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
* <code>AuthenticationDao</code> will need to generate the expected password in a corresponding manner.</p>
*
* @param request so that request attributes can be retrieved
*
* @return the password that will be presented in the <code>Authentication</code> request token to the
* <code>AuthenticationManager</code>
*/
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
/**
* Enables subclasses to override the composition of the username, such as by including additional values
* and a separator.
*
* @param request so that request attributes can be retrieved
*
* @return the changePassword Flag that will be presented in the Session so it can be processed later
*/
protected String obtainChangePassword(HttpServletRequest request) {
return request.getParameter(changePasswordParameter);
}
/**
* Enables subclasses to override the composition of the username, such as by including additional values
* and a separator.
*
* @param request so that request attributes can be retrieved
*
* @return the username that will be presented in the <code>Authentication</code> request token to the
* <code>AuthenticationManager</code>
*/
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
/**
* Provided so that subclasses may configure what is put into the authentication request's details
* property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details set
*/
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
/**
* Sets the parameter name which will be used to obtain the username from the login request.
*
* @param usernameParameter the parameter name. Defaults to "j_username".
*/
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.usernameParameter = usernameParameter;
}
public void setChangePasswordParameter(String changePasswordParameter) {
Assert.hasText(changePasswordParameter,"Change Password parameter must not be empty or null");
this.changePasswordParameter = changePasswordParameter;
}
/**
* Sets the parameter name which will be used to obtain the password from the login request..
*
* @param passwordParameter the parameter name. Defaults to "j_password".
*/
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
this.passwordParameter = passwordParameter;
}
/**
* Defines whether only HTTP POST requests will be allowed by this filter.
* If set to true, and an authentication request is received which is not a POST request, an exception will
* be raised immediately and authentication will not be attempted. The <tt>unsuccessfulAuthentication()</tt> method
* will be called as if handling a failed authentication.
* <p>
* Defaults to <tt>true</tt> but may be overridden by subclasses.
*/
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getUsernameParameter() {
return usernameParameter;
}
public final String getPasswordParameter() {
return passwordParameter;
}
public final String getChangePasswordParameter() {
return changePasswordParameter;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment