如何使用 Spring 安全性获取会话超时消息
Posted
技术标签:
【中文标题】如何使用 Spring 安全性获取会话超时消息【英文标题】:How to get session time out message using Spring security 【发布时间】:2016-08-11 01:16:06 【问题描述】:我想在会话到期时获取会话超时消息。下面是我的 spring-security.xml
<http auto-config="true" use-expressions="true">
<logout logout-success-url="/" invalidate-session="true" logout-url="/LogOut"/>
<form-login login-page="/Login" username-parameter="Name" password-parameter="Pwd"/>
<session-management invalid-session-url="/?timeout=true">
<concurrency-control max-sessions="1" expired-url="/Timeout?timeout=true" />
</session-management>
</http>
据我所知,当会话过期时使用上面的代码,它应该重定向到/?timeout=true OR /Timeout?timeout=true
。注销时应该转到/
。但在我的注销情况下,它也重定向到invalid-session-url
,所以对于正常注销和会话超时,我总是得到超时。
请帮我区分一下。
更新
/logout
请求包含
session = request.getSession();
session.invalidate();
session = null;
【问题讨论】:
invalid-session-url
当你没有正确地使会话失效时触发,你能说明你是如何使会话失效的吗?
在您的 web.xml 中,应用程序启动时指定的默认页面是什么?
我没有指定任何东西..for "/" url 我已经加载了登录页面
【参考方案1】:
我解决了!通过编写一个过滤器,而不是依赖于 Spring-security。
如果有人有兴趣,他们可以使用以下代码:-
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.filter.OncePerRequestFilter;
public class FilterToGetTimeOut extends OncePerRequestFilter
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException
try
if(request.getRequestURI().equals("/") || request.getRequestURI().equals("/Login/"))
if(request.getSession().getAttribute("login") != null && (Boolean)request.getSession().getAttribute("login") == true)
response.sendRedirect(URL); //After login page
else if(request.getSession().getAttribute("login") == null && !request.getRequestURI().equals("/LogOut"))
response.sendRedirect(request.getContextPath()+"/?timeout=true"); //If timeout is true send session timeout error message to JSP
filterChain.doFilter(request, response);
catch (Exception e)
//Log Exception
在web.xml
中添加这个过滤器。
<filter>
<filter-name>FilterToGetTimeOut </filter-name>
<filter-class>package.FilterToGetTimeOut </filter-class>
</filter>
<filter-mapping>
<filter-name>FilterToGetTimeOut</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
所以现在会话也失效了,我也可以处理会话超时。
【讨论】:
“登录后页面”sn-p 中的 var URL 是什么? 我不明白这条线是做什么的? response.sendRedirect(URL) 这将加载您将提到的 URL....它将重定向.....response.sendRedirect("/errorLogin");
它将转到http:localhost:xxx/xxxx/errorLogin
【参考方案2】:
我建议您使用以下方式注销:
HttpSession session= request.getSession(false);
SecurityContextHolder.clearContext();
if(session != null)
session.invalidate();
for(Cookie cookie : request.getCookies())
cookie.setMaxAge(0);
【讨论】:
我按照你的回答试过了,总是无法获得会话超时expired-url
用于会话过期,这意味着如果应用程序检测到用户超过max-sessions
,在这种情况下超过 1 个会话,那么 spring 将重定向到 expired-url
。我的回答是确保您的注销不会转到invalid-session-url
。如果你想让用户在一定时间后自动注销,你可以使用jquery。
如果我删除 session.invalidate ,实际上在注销时它也会相同
抱歉忘了一件事,如果你想使用我的答案,你需要删除spring-security.xml中的在您的情况下,当用户注销时,会话首先失效,然后会话管理将被触发。当会话管理进来,发现会话已经消失时,会话超时页面将被重定向。所以最好将logout标签的invalidate-session设置为false。
<logout logout-success-url="/" invalidate-session="false" logout-url="/LogOut"/>
【讨论】:
在提到 invalidate-session='false' 时也用于注销它的重定向到 invalidate-url【参考方案4】:请在您的控制器中定义注销成功 url 的请求映射,并从那里重定向到主页。例如替换您的映射如下
<http auto-config="true" use-expressions="true">
<logout logout-success-url="/logoutSucess" invalidate-session="true" logout-url="/LogOut"/>
<form-login login-page="/Login" username-parameter="Name" password-parameter="Pwd"/>
<session-management invalid-session-url="/?timeout=true">
<concurrency-control max-sessions="1" expired-url="/Timeout?timeout=true" />
</session-management>
使用@RequestMapping(value="/logoutSucess" method=RequestMethod.GET) 在控制器中定义这个/logoutSucess
【讨论】:
【参考方案5】:我也有类似的问题,比如
-
如果您使用某些用户登录,请说 zzzz
您关闭了浏览器
您再次尝试使用同一用户 zzzz 登录
登录失败并显示超出最大会话的消息
我的 spring 安全文件中的代码是:
<session-management invalid-session-url="/?timeout=true">
<concurrency-control max-sessions="1" expired-url="/logout?timeout" />
我通过在 web.xml 文件中添加会话超时条目解决了这个问题。 我将会话超时值设置为 5 分钟,构建应用程序并部署。 它工作正常。
这可能会对某人有所帮助。
谢谢, 阿图尔
【讨论】:
以上是关于如何使用 Spring 安全性获取会话超时消息的主要内容,如果未能解决你的问题,请参考以下文章
Spring消息传递+安全如何通过websockets登录?
如何使用 Spring Boot 嵌入式 tomcat 设置会话超时
会话超时后,Spring 安全性不会重定向到上次请求的页面登录