简体   繁体   English

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

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

I am sorry if the title is not clear enough. 如果标题不够明确,我很抱歉。 Here are the details. 这是详细信息。

Background 背景

I am working on Spring based application that uses Spring 3.1.1 and Spring security 3.1.0. 我正在使用Spring 3.1.1和Spring security 3.1.0的基于Spring的应用程序。 Here is the relevant fragment of our descriptor: 这是我们描述符的相关片段:

<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>

The "sign-out" link on the web page refers to URL like ROOT-URL/j_spring_security_logout . 网页上的“注销”链接指的是ROOT-URL/j_spring_security_logoutROOT-URL/j_spring_security_logout So, clicking on this URL brings us to login page ( login.jsp ) and can login again successfully. 因此,单击此URL会将我们带到登录页面( login.jsp )并可以再次成功登录。

Problem 问题

If user logs-in into the application, waits until session is expired and then tries to sign-out he arrives to login page. 如果用户登录到应用程序,等待会话过期,然后尝试注销他到达登录页面。 This is fine. 这可以。 Then he types correct credentials and clicks login button. 然后他键入正确的凭据并单击登录按钮。 Now he is redirected to the same login page where username and password fields are empty instead of enter to the application. 现在,他被重定向到同一个登录页面,其中用户名和密码字段为空,而不是输入到应用程序。 The second attempt to log-in succeeds. 第二次登录尝试成功。

Important: this happens only if the user was logged-in before, the session was expired and he tried to log-out. 重要提示:只有在用户登录之前,会话已过期并且他尝试注销时才会发生这种情况。 It does not happens for example if user clicks any other link after session expiration. 例如,如果用户在会话到期后单击任何其他链接,则不会发生这种情况。 In this case he is redirected to login page and can successfully login from the first attempt. 在这种情况下,他被重定向到登录页面,并可以从第一次尝试成功登录。

Analysis 分析

My investigation showed the following. 我的调查显示如下。 We arrive to the login page twice due to HTTP redirect caused by SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess() and happens because requestCache contains request to login page. 由于由SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess()引起的HTTP重定向,我们到达登录页面两次,因为requestCache包含登录页面请求。 requestCache is variable of type HttpSessionRequestCache that stores "cached" request in session attribute "SPRING_SECURITY_SAVED_REQUEST" . requestCacheHttpSessionRequestCache类型的变量,它在会话属性"SPRING_SECURITY_SAVED_REQUEST"中存储“缓存”请求。

In normal situation this cache is used for redirecting to page requested by not-authenticated user after his authentication. 在正常情况下,此高速缓存用于在其认证之后重定向到未经认证的用户请求的页面。

But here is what happens in our case. 但这是我们的情况。 The user logs-in. 用户登录。 Then his session is expired. 然后他的会话到期了。 Then he clicks link to log-out. 然后他点击链接登出。 Since session is expired user is redirected to 'j_spring_security_logout' that redirects him to login page. 会话过期后,用户将被重定向到“j_spring_security_logout”,将其重定向到登录页面。

Somewhere on this way the login URL is cached as "requested", so when user logs in he is redirected to requested URL, ie to login page. 在某种程度上,登录URL被缓存为“已请求”,因此当用户登录时,他被重定向到请求的URL,即登录页面。 When redirect happens the cached URL is removed, so infinite loop does not happen; 当重定向发生时,缓存的URL被删除,因此不会发生无限循环; second attempt to log-in succeeds. 第二次尝试登录成功。

Here are the relevant code reference: 以下是相关的代码参考:

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

that does the following (lines 183-184): 执行以下操作(第183-184行):

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

But the requested URL at this point is login page. 但此时请求的URL是登录页面。 So, the login page is cached. 因此,登录页面被缓存。

It looks like the saveRequest() just should not be called at this point, eg this smells as a bug in Spring framework... 看起来saveRequest()不应该调用saveRequest() ,例如这就像Spring框架中的一个bug ...

I have solution to this problem and I will post it here. 我有解决这个问题的方法,我会在这里发布。 But my solution looks as a patch for me, so I hope somebody know the "right" solution. 但我的解决方案看起来像是一个补丁,所以我希望有人知道“正确”的解决方案。

Thanks in advance. 提前致谢。

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

No reason to put any constraints on the login-page itself. 没有理由对登录页面本身施加任何限制。

Try This, it works for me : 试试这个,它对我有用:

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

Replace: 更换:

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

by: 通过:

.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"); 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”);

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

暂无
暂无

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

相关问题 会话超时后,用户再次尝试登录后,注销将用户重定向到登录页面 - Logout redirects user to login page again after user tries login again when session timeouts 如何在Java Web应用程序中过期会话时重定向到“登录”页面? - How to redirect to Login page when Session is expired in Java web application? 在JSF / Spring中会话超时时重定向到登录,或者在会话停用时(或在给定时间为idel时)自动注销 - Redirecting to login when session timeout in JSF/Spring or automatic logout when session deactivate(or idel for a given time) 会话到期时重定向到登录页面时是否为空指针异常? - Null pointer exception while redirecting to the login page when the session expires? 在 Wicket 9 中,当用户的会话在某些页面中过期时,他们被重定向到登录页面而不是会话过期页面 - In Wicket 9, when the user's session expires in certain pages, they are redirected to the login page not the Session Expired page Spring + CAS注销后重定向到登录页面 - Spring + CAS Redirect to login page after logout 注销后如何在登录页面上重定向 - How to redirect on login page after logout 会话过期后,Spring MVC会将用户重定向到登录页面 - Spring MVC redirect user to login page once session is expired 重定向到登录页面时如何保持闪存 - How to keep flash when redirecting to the login page 单击注销按钮,终止会话并重定向到登录页面 - Kill session and redirect to login page on click of logout button
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM