Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle expired session using Spring Security and jQuery?

I'm using Spring Security and jQuery in my application. Main page uses loading content dynamically into tabs via AJAX. And all is OK, however sometimes I've got the login page inside my tab and if I type credentials I will be redirected to the content page without tabs.

So I'd like to handle this situation. I know some of the people use AJAX authentication, but I'm not sure it's suitable for me because it looks quite complicated for me and my application doesn't allow any access without log into before. I would like to just write a global handler for all AJAX responses that will do window.location.reload() if we need to authenticate. I think in this case it's better to get 401 error instead of standard login form because it's easier to handle.

So,

1) Is it possible to write global error handler for all jQuery AJAX requests?

2) How can I customize behavior of Spring Security to send 401 error for AJAX requests but for regular requests to show standard login page as usual?

3) May be you have more graceful solution? Please share it.

Thanks.

like image 418
viator Avatar asked Jul 26 '10 22:07

viator


1 Answers

Here's an approach that I think is quite simple. It's a combination of approaches that I've observed on this site. I wrote a blog post about it: http://yoyar.com/blog/2012/06/dealing-with-the-spring-security-ajax-session-timeout-problem/

The basic idea is to use an api url prefix (i.e. /api/secured) as suggested above along with an authentication entry point. It's simple and works.

Here's the authentication entry point:

package com.yoyar.yaya.config;  import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;  import javax.servlet.ServletException; import javax.servlet.http.*; import java.io.IOException;  public class AjaxAwareAuthenticationEntryPoint               extends LoginUrlAuthenticationEntryPoint {      public AjaxAwareAuthenticationEntryPoint(String loginUrl) {         super(loginUrl);     }      @Override     public void commence(         HttpServletRequest request,          HttpServletResponse response,          AuthenticationException authException)              throws IOException, ServletException {          boolean isAjax              = request.getRequestURI().startsWith("/api/secured");          if (isAjax) {             response.sendError(403, "Forbidden");         } else {             super.commence(request, response, authException);         }     } } 

And here's what goes in your spring context xml:

<bean id="authenticationEntryPoint"   class="com.yoyar.yaya.config.AjaxAwareAuthenticationEntryPoint">     <constructor-arg name="loginUrl" value="/login"/> </bean>  <security:http auto-config="true"   use-expressions="true"   entry-point-ref="authenticationEntryPoint">     <security:intercept-url pattern="/api/secured/**" access="hasRole('ROLE_USER')"/>     <security:intercept-url pattern="/login" access="permitAll"/>     <security:intercept-url pattern="/logout" access="permitAll"/>     <security:intercept-url pattern="/denied" access="hasRole('ROLE_USER')"/>     <security:intercept-url pattern="/" access="permitAll"/>     <security:form-login login-page="/login"                          authentication-failure-url="/loginfailed"                          default-target-url="/login/success"/>     <security:access-denied-handler error-page="/denied"/>     <security:logout invalidate-session="true"                      logout-success-url="/logout/success"                      logout-url="/logout"/> </security:http> 
like image 119
Matt Friedman Avatar answered Sep 26 '22 10:09

Matt Friedman