【问题标题】:How to get session time out message using Spring security如何使用 Spring 安全性获取会话超时消息
【发布时间】: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 我已经加载了登录页面

标签: java spring spring-mvc session spring-security


【解决方案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中的。您能说出您希望系统如何运行吗?
  • 注销时 SpringContext 应该清除,会话应该为空,并且会话超时错误消息应该出现。
【解决方案3】:

在您的情况下,当用户注销时,会话首先失效,然后会话管理将被触发。当会话管理进来,发现会话已经消失时,会话超时页面将被重定向。所以最好将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】:

    我也有类似的问题,比如

    1. 如果您使用某些用户登录,请说 zzzz
    2. 您关闭了浏览器
    3. 您再次尝试使用同一用户 zzzz 登录
    4. 登录失败并显示超出最大会话的消息

    我的 spring 安全文件中的代码是:

    <session-management invalid-session-url="/?timeout=true">
    <concurrency-control max-sessions="1" expired-url="/logout?timeout" />
    

    我通过在 web.xml 文件中添加会话超时条目解决了这个问题。 我将会话超时值设置为 5 分钟,构建应用程序并部署。 它工作正常。

    这可能会对某人有所帮助。

    谢谢, 阿图尔

    【讨论】:

      猜你喜欢
      • 2014-04-28
      • 2015-08-05
      • 2014-07-17
      • 1970-01-01
      • 2012-08-04
      • 1970-01-01
      • 2022-09-28
      • 2023-03-31
      • 2012-03-14
      相关资源
      最近更新 更多