I've been using Spring Security 3.0 for our website login mechanism using a dedicated login webpage. Now I need that login webpage to instead be a lightbox/popup window on every webpage in our site where upon logging in I get an AJAX result whether it was successful or not. What's the best way to go about this with Spring Security and Spring webmvc 3.0?
Asked
Active
Viewed 2.0k times
16
2 Answers
13
At the client-side you may simulate a normal form submission to your login url via ajax. For example, in jQuery:
$.ajax({
url: "${pageContext.request.contextPath}/j_spring_security_check",
type: "POST",
data: $("#loginFormName").serialize(),
beforeSend: function (xhr) {
xhr.setRequestHeader("X-Ajax-call", "true");
},
success: function(result) {
if (result == "ok") {
...
} else if (result == "error") {
...
}
}
});
At the server side, you may customize AuthenticationSuccessHandler
and AuthenticationFailureHandler
to return a value instead of redirect. Because you probably need a normal login page as well (for attempt to access a secured page via direct url), you should tell ajax calls from normal calls, for example, using header:
public class AjaxAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private AuthenticationSuccessHandler defaultHandler;
public AjaxAuthenticationSuccessHandler() {
}
public AjaxAuthenticationSuccessHandler(AuthenticationSuccessHandler defaultHandler) {
this.defaultHandler = defaultHandler;
}
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication auth)
throws IOException, ServletException {
if ("true".equals(request.getHeader("X-Ajax-call"))) {
response.getWriter().print("ok");
response.getWriter().flush();
} else {
defaultHandler.onAuthenticationSuccess(request, response, auth);
}
}
}
-
i didnt get this working . user name and password are coming null from requst – gsagrawal Nov 23 '12 at 13:35
7
I did something similar (thanks axtavt):
public class AjaxAuthenticationSuccessHandler extends
SimpleUrlAuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication auth)
throws IOException, ServletException {
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
response.getWriter().print(
"{success:true, targetUrl : \'"
+ this.getTargetUrlParameter() + "\'}");
response.getWriter().flush();
} else {
super.onAuthenticationSuccess(request, response, auth);
}
}}
I chose to extend the simple success handler for the default behavior on non-Ajax requests. Here's the XML to make it work:
<http auto-config="false" use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">
<custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
...
...
</http>
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/index.do" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
<beans:bean id="authenticationFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"/>
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
<beans:property name="authenticationFailureHandler" ref="failureHandler"/>
<beans:property name="authenticationSuccessHandler" ref="successHandler"/>
</beans:bean>
<beans:bean id="successHandler" class="foo.AjaxAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/login.html"/>
</beans:bean>
<beans:bean id="failureHandler" class="foo.AjaxAuthenticationFailureHandler" />

Peter Hawkins
- 373
- 4
- 7