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
?
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 authenticationSimpleUrlAuthenticationFailureHandler
-- 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>
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