繁体   English   中英

在会话过期时尝试注销导致登录后重定向到登录页面

[英]Redirecting to login page after login caused by attempt to logout when session is expired

如果标题不够明确,我很抱歉。 这是详细信息。

背景

我正在使用Spring 3.1.1和Spring security 3.1.0的基于Spring的应用程序。 这是我们描述符的相关片段:

<security:http auto-config='true'>      
    <security:intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <security:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <security:intercept-url pattern="/**" access="ROLE_USER" />     
    <security:form-login login-page='/login' authentication-failure-url="/login?authfailed=true"/>              
</security:http>

网页上的“注销”链接指的是ROOT-URL/j_spring_security_logoutROOT-URL/j_spring_security_logout 因此,单击此URL会将我们带到登录页面( login.jsp )并可以再次成功登录。

问题

如果用户登录到应用程序,等待会话过期,然后尝试注销他到达登录页面。 这可以。 然后他键入正确的凭据并单击登录按钮。 现在,他被重定向到同一个登录页面,其中用户名和密码字段为空,而不是输入到应用程序。 第二次登录尝试成功。

重要提示:只有在用户登录之前,会话已过期并且他尝试注销时才会发生这种情况。 例如,如果用户在会话到期后单击任何其他链接,则不会发生这种情况。 在这种情况下,他被重定向到登录页面,并可以从第一次尝试成功登录。

分析

我的调查显示如下。 由于由SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess()引起的HTTP重定向,我们到达登录页面两次,因为requestCache包含登录页面请求。 requestCacheHttpSessionRequestCache类型的变量,它在会话属性"SPRING_SECURITY_SAVED_REQUEST"中存储“缓存”请求。

在正常情况下,此高速缓存用于在其认证之后重定向到未经认证的用户请求的页面。

但这是我们的情况。 用户登录。 然后他的会话到期了。 然后他点击链接登出。 会话过期后,用户将被重定向到“j_spring_security_logout”,将其重定向到登录页面。

在某种程度上,登录URL被缓存为“已请求”,因此当用户登录时,他被重定向到请求的URL,即登录页面。 当重定向发生时,缓存的URL被删除,因此不会发生无限循环; 第二次尝试登录成功。

以下是相关的代码参考:

ExceptionTranslationFilter.handleSpringSecurityException()调用sendStartAuthentication() (第168行)

执行以下操作(第183-184行):

    SecurityContextHolder.getContext().setAuthentication(null);
    requestCache.saveRequest(request, response);

但此时请求的URL是登录页面。 因此,登录页面被缓存。

看起来saveRequest()不应该调用saveRequest() ,例如这就像Spring框架中的一个bug ...

我有解决这个问题的方法,我会在这里发布。 但我的解决方案看起来像是一个补丁,所以我希望有人知道“正确”的解决方案。

提前致谢。

<intercept-url pattern="/login.jsp*" access="permitAll" />
<intercept-url pattern="/login*" access="permitAll" />

没有理由对登录页面本身施加任何限制。

试试这个,它对我有用:

<security:form-login 
        login-page="/login.jsp" 
        default-target-url="/home.jsp"
        always-use-default-target="true" 
        authentication-failure-url="/login?authfailed=true"/>

更换:

.defaultSuccessUrl("/paginas/geral/index.jsf")

通过:

.defaultSuccessUrl("/paginas/geral/index.jsf", true)

http.authorizeRequests()。anyRequest()。authenticated()。and()。formLogin()。loginPage(“/ login.jsf”)。permitAll()。usernameParameter(“login”)。passwordParameter(“senha”)。 defaultSuccessUrl(“/ paginas / geral / index.jsf”,true).failureUrl(“/ login.jsf?invalid = true”);

这个对我有用。 (spring-security-web:4.1.3.RELEASE)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM