![](/img/trans.png)
[英]Logout redirects user to login page again after user tries login again when session timeouts
[英]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_logout
等ROOT-URL/j_spring_security_logout
。 因此,单击此URL会将我们带到登录页面( login.jsp
)并可以再次成功登录。
问题
如果用户登录到应用程序,等待会话过期,然后尝试注销他到达登录页面。 这可以。 然后他键入正确的凭据并单击登录按钮。 现在,他被重定向到同一个登录页面,其中用户名和密码字段为空,而不是输入到应用程序。 第二次登录尝试成功。
重要提示:只有在用户登录之前,会话已过期并且他尝试注销时才会发生这种情况。 例如,如果用户在会话到期后单击任何其他链接,则不会发生这种情况。 在这种情况下,他被重定向到登录页面,并可以从第一次尝试成功登录。
分析
我的调查显示如下。 由于由SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess()
引起的HTTP重定向,我们到达登录页面两次,因为requestCache
包含登录页面请求。 requestCache
是HttpSessionRequestCache
类型的变量,它在会话属性"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.