I've the following in my Spring Security XML:
<form-login login-page="/login"
authentication-failure-url="/login/failure" />
I want to get the username on authentication failure. I read over the net that it can be got from SPRING_SECURITY_LAST_USERNAME, but my question is:
How can i access it either in: 1) the spring security XML e.g. something like
authentication-failure-url="/login/failure/SPRING_SECURITY_LAST_USERNAME"
2) or the controller that's handling /login/failure mapping.
Please help. I'm stuck! :(
It's deprecated:
/**
* @deprecated If you want to retain the username, cache it in a customized {@code AuthenticationFailureHandler}
*/
@Deprecated
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
So you need to implement your own AuthenticationFailureHandler
.
I implemented 1) strategy: (remember that username can contain some characters that are inappropriate inside URL!)
package some.package;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UsernameInURLAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
private String urlPrefix;
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
private String formUsernameKey = UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY;
public UsernameInURLAuthenticationFailureHandler(String urlPrefix) {
this.urlPrefix = urlPrefix;
}
//Failure logic:
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
//We inherited that method:
saveException(request, exception);
//Prepare URL:
String username = request.getParameter(formUsernameKey);
String redirectUrl = urlPrefix + username;
//Redirect:
redirectStrategy.sendRedirect(request, response, redirectUrl);
}
//Getters and setters:
public String getUrlPrefix() {
return urlPrefix;
}
public void setUrlPrefix(String urlPrefix) {
this.urlPrefix = urlPrefix;
}
public String getFormUsernameKey() {
return formUsernameKey;
}
public void setFormUsernameKey(String formUsernameKey) {
this.formUsernameKey = formUsernameKey;
}
public RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
}
Bean:
<bean class="some.package.UsernameInURLAuthenticationFailureHandler">
<!-- prefix: -->
<constructor-arg value="/login/failure/"/>
</bean>
You can easily implement 2) strategy. Just save the username as one of the session attributes inside onAuthenticationFailure
method instead of adding username to the URL.
You can easily set your own handler:
<form-login>
Attributes
authentication-failure-handler-ref
Can be used as an alternative to authentication-failure-url, giving you full control over the navigation flow after an authentication failure. The value should be he name of an AuthenticationFailureHandler bean in the application context.
More in docs: CLICK
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With