Spring安全性+ Ajax会话超时问题

ale*_*cci 11 ajax spring spring-mvc spring-security

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

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

问题是会话超时后的第一个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请求,我不希望重定向到登录页面.

有任何想法吗?

<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>
Run Code Online (Sandbox Code Playgroud)

这是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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

nge*_*eek 5

确认使用Spring Boot和Spring Security以编程方式结合安全性也可以很好地工作,以编程方式设置安全性而无需任何必需的XML,例如:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/admin**").hasRole("ADMIN")
            // everything else
            .anyRequest().fullyAuthenticated()
        .and()
            .exceptionHandling().authenticationEntryPoint(new AjaxAwareAuthenticationEntryPoint("/login"));
}
Run Code Online (Sandbox Code Playgroud)


ale*_*cci -1

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