Spring security + Ajax 会话超时问题 [英] Spring security + Ajax session timeout issue

查看:29
本文介绍了Spring security + Ajax 会话超时问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 Spring MVC 构建并使用 Spring 安全保护的应用程序,一堆控制器是全部受保护的 JSON 休息服务.我正在使用 LoginUrlAuthenticationEntryPoint 来检测 AJAX 请求并在发生会话超时时发送 403 错误代码 - 所有其他请求都被重定向回登录页面.

I have an app build with Spring MVC and secured with Spring security, a bunch of the controllers are JSON rest services that are all protected. I'm using LoginUrlAuthenticationEntryPoint to detect AJAX requests and send 403 ERROR CODE if session timeout occurs - all other requests just get redirected back to login page.

下面是 Spring Security XML 片段和 authenticationEntryPoint java 类.

Below is the Spring Security XML snippet and the authenticationEntryPoint java class.

问题是会话超时后的第一个 AJAX 请求,Spring 重定向到登录页面并返回登录页面 HTML,如果我再次尝试执行 AJAX 请求(重定向发生后)authenticationEntryPoint 执行并返回 HTTP 错误代码 403.我使用这种机制尝试了同样的事情 http://distigme.wordpress.com/2012/11/01/ajax-and-spring-security-form-b​​ased-login/ 并且发生了完全相同的事情(在第一个 AJAX 请求时会发生重定向,返回所有后续 AJAX 请求 HTTP 403).对于会话超时的 AJAX 请求,我不想重定向到登录页面.

The issue is that the first AJAX Request after session timeout, Spring redirects to login page and the returns login page HTML, if I attempt to do AJAX request again (after redirect happens) the authenticationEntryPoint executes and HTTP Error Code 403 is returned. I have attempted the same thing using this mechanism http://distigme.wordpress.com/2012/11/01/ajax-and-spring-security-form-based-login/ and the same exact thing happens (on first AJAX request a redirect occurs, all subsequent AJAX requests HTTP 403 is returned). I do not want to get Redirect to login page for AJAX requests where session is timed out.

有什么想法吗?

<beans:bean id="authenticationEntryPoint"  class="mojo.ocs.web.AjaxAwareAuthenticationEntryPoint">
    <beans:constructor-arg name="loginUrl" value="/login"/>
</beans:bean>
<!-- ENTRY POINT REF IMPLEMENTATION -->
<http auto-config="true" use-expressions="true" access-denied-page="/accessdenied" entry-point-ref="authenticationEntryPoint">
    <intercept-url pattern="/login" access="isAnonymous()"/>
    <intercept-url pattern="/loginfailed" access="isAnonymous()"/>
    <intercept-url pattern="/welcome" access="isAuthenticated()" />
    <intercept-url pattern="/" access="isAuthenticated()" />
    <intercept-url pattern="/private_res/**" access="isAuthenticated()" />
    <intercept-url pattern="/tne/**" access="isAuthenticated()" />
    <intercept-url pattern="/team_reports/**" access="isAuthenticated()" />
    <form-login login-page="/login" default-target-url="/welcome" always-use-default-target="true" authentication-failure-url="/loginfailed" />
    <logout delete-cookies="JSESSIONID"  logout-success-url="/logout" invalidate-session="true"/>
    <session-management invalid-session-url="/login" />
</http>

这是 LoginAuthenticationEntryPoint:

Here is the LoginAuthenticationEntryPoint:

public class AjaxAwareAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint     
{
    public AjaxAwareAuthenticationEntryPoint(String loginUrl) {
        super(loginUrl);
    }

    @Override
    public void commence(
        HttpServletRequest request,
        HttpServletResponse response,
        AuthenticationException authException)
        throws IOException, ServletException {
        String ajaxHeader = ((HttpServletRequest) request).getHeader("X-Requested-With");
        boolean isAjax = "XMLHttpRequest".equals(ajaxHeader);
        if (isAjax) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Ajax REquest Denied (Session Expired)");
        } else {
            super.commence(request, response, authException);
        }
    }
}

推荐答案

我通过实现自己的自定义过滤器解决了这个问题,将它放在 ANONYMOUS_FILTER 之前,如果 Spring 主体不存在则返回 403.

I fixed this issue by implementing by own custom filter, placing it before ANONYMOUS_FILTER and return 403 if the Spring principal doesn't exist.

这篇关于Spring security + Ajax 会话超时问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆