Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include SPRING_SECURITY_LAST_USERNAME in authentication failure url?

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! :(

like image 751
LittleLebowski Avatar asked Feb 18 '23 09:02

LittleLebowski


1 Answers

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

like image 147
Maciej Ziarko Avatar answered Mar 15 '23 23:03

Maciej Ziarko