Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

define authentication-failure-url to be `{currentpage}?login_error=1`?

I am using Spring MVC, Spring security and Apache tiles.
I have login div that appears in every page (in case the user is not authenticated yet).
This is the configuration:

<http use-expressions="true">
    <intercept-url pattern="/index.jsp" access="permitAll" />
    <intercept-url pattern="/registration.html" access="permitAll" />
    <intercept-url pattern="/about.html" access="permitAll" />
    <intercept-url pattern="/search.html" access="permitAll" />
    <intercept-url pattern="/login.html" access="permitAll" />
    <intercept-url pattern="/logout.html" access="permitAll" />
    <intercept-url pattern="/post.html" access="hasAnyRole('USER')" />
    <intercept-url pattern="/**" access="denyAll" />
    <form-login default-target-url='/search.html'
                authentication-failure-url="/login.html?login_error=1" />
    <logout logout-success-url="/logout.html" />
</http>   

The problem is: Assume the user enters to search.html and enters invalid login details. But then the user redirect to /login.html?login_error=1 instead of redirecting to search.html?login_error=1. How can I define authentication-failure-url to be {currentpage}?login_error=1 ?

like image 443
Naor Avatar asked Jan 18 '23 15:01

Naor


1 Answers

You need to customize the SimpleUrlAuthenticationFailureHandler a bit, for example by an new RedirectStrategy.

Before starting: you should have a look at the source of this classes to understand what they do:

  • UsernamePasswordAuthenticationFilter and its super class AbstractAuthenticationProcessingFilter -- That is the filter that triggers the authentication
  • SimpleUrlAuthenticationFailureHandler -- this is responsible to do something if an authentication is required (it is invoked by `SimpleUrlAuthenticationFailureHandler).
  • DefaultRedirectStrategy -- used by SimpleUrlAuthenticationFailureHandler to do the redirct.
  • FormLoginBeanDefinitionParser -- parses the XML security:form-login element -- You should read it to understand what how the beans are created and referenced!!

You should write your own RedirectStrategy, lets call it MyAppendParameterRedirectStrategy (may have first a look at DefaultRedirectStrategy). It needs only one method: void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url). At least you should do the same like DefaultRedirectStrategy but instead of returning the (login) url in the calculateRedirectUrl you should calculate the url like stripParams(getRequestURL()) + "?login_error=1"

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.web.RedirectStrategy;

public class MyAppendParameterRedirectStrategy implements RedirectStrategy {

    @Override
    public void sendRedirect(final HttpServletRequest request, final HttpServletResponse response, final String url) throws IOException {
        String redirectUrl = calculateRedirectUrl(request.getRequestURL().toString());
        redirectUrl = response.encodeRedirectURL(redirectUrl);
        response.sendRedirect(redirectUrl);
    }

    private String calculateRedirectUrl(final String requestUrl) {
        //Attention this parameter striping is only proof of concept!
        return StringUtils.substringBeforeLast(requestUrl, "?") + "?login_error=1";
    }
}

The Second part is that you need to change the spring configuration (therefore you should read the classes I mentioned about) I think the configuration should be like this (but I do not have tested it):

<security:form-login login-processing-url="/login/j_spring_security_check" login-page="/login" authentication-failure-handler-ref="simpleUrlAuthenticationFailureHandler"/>

<bean id="SimpleUrlAuthenticationFailureHandler"
      class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
   <property="defaultFailureUrl" value="NotNullButWeDoNotUseIt" />
   <property="redirectStrategy">
      <bean class="MyAppendParameterRedirectStrategy"/>
   </property>
</bean>
like image 66
Ralph Avatar answered Jan 21 '23 16:01

Ralph