首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Spring安全自动注销

如何使用Spring安全自动注销
EN

Stack Overflow用户
提问于 2015-01-05 08:18:41
回答 6查看 37.7K关注 0票数 13

我有一个spring应用程序,我使用Spring安全性进行了用户身份验证。

一切都很好。登录和注销工作完美!

现在,我想实现以便自动注销。例如,如果用户打开了大约30分钟的窗口而什么也不做(例如会话过期了),系统应该自动注销。我如何实现这一点?

它可能由客户端实现(我每1分钟发送一次请求,并检查会话是否结束)。但我不能从春天就自动这么做吗?

我有一个配置:

代码语言:javascript
复制
<http auto-config="true" use-expressions="true">


        <intercept-url pattern="/admin**" />
        <access-denied-handler error-page="/403" />

        <form-login login-page="/login" 
            default-target-url="/admin"
            authentication-failure-url="/login?error" 
            username-parameter="NAME"
            password-parameter="PASSWORD"  />

        <logout invalidate-session="true" 
             logout-success-url="/login?logout"/>

    </http>

在web.xml中

代码语言:javascript
复制
<session-config>
  <session-timeout>1</session-timeout>
</session-config>

1分钟后,我看到那次会议被毁了。1分钟后结束治疗。但是页面没有重定向到/login?logout

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2015-01-05 08:31:26

如何使用安全配置。?我希望下面的配置:将工作。

applicationContext.xml

代码语言:javascript
复制
 --namespace-> xmlns:security="http://www.springframework.org/schema/security"

        <security:logout invalidate-session="true"
                        success-handler-ref="Logout"
                        logout-url="/logout.html" />
        </security:http>

web.xml

代码语言:javascript
复制
 <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>

而且,您需要编写自己的程序,因为成功处理程序-ref=“logout”是用于注销的自定义处理程序:

注销@组件

代码语言:javascript
复制
public class Logout extends SimpleUrlLogoutSuccessHandler {

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {

        if (authentication != null) {
            // do something 
        }

        setDefaultTargetUrl("/login");
        super.onLogoutSuccess(request, response, authentication);       
    }
}
票数 6
EN

Stack Overflow用户

发布于 2019-08-21 19:42:43

无论是spring安全性、spring还是servlet,如果没有完善的客户端逻辑,自动注销是不可能的。

考虑申请将有两种类型的请求

  • AJAX和
  • 表单提交/页面重新加载

自动注销需要非常计算的逻辑。以下列方式显示我的自动退出功能实现

优势。

  1. 没有使用额外的调用/请求来实现这一点。考虑性能影响,如果超过10k的活跃用户和额外的调用,以实现自动注销。
  2. 使用标记的一行配置。
  3. 即使用户打开多个选项卡或多个窗口,也能完美地工作。
  4. 它会在30秒的会话失效前通知您,因此如果您已经填写了表单而没有提交,则可以保持会话活动(只需单击一次扩展会话)。因此,用户不太可能丢失未保存的数据。

用法

1.在所需的JSP页面中包括自动注销脚本,如下所示

代码语言:javascript
复制
    ....
    </body>
    <jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>

2.创建一个JSP页面,autoologout-script.jsp并添加下面的代码。注意:不需要编辑/配置

代码语言:javascript
复制
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<script>
$(document).ready(function()
{
    var timeOutTimeInSeconds = ${ timeOutTimeInSeconds }; 
    var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

    var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
    var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
    var badgeTimerId;
    window.localStorage.setItem("AjaxRequestFired", new Date());

    function redirectToLoginPage(){
        //location.href =  '<c:url value="/" />'+'${loginPageUrl}';
        window.location.reload();
    }

    $(document).ajaxComplete(function () {
        resetTimer();
    });

    $(window).bind('storage', function (e) {
         if(e.originalEvent.key == "AjaxRequestFired"){
             console.log("Request sent from another tab, hence resetting timer")
             resetTimer();
         }
    });

    function resetTimer()
    {
        showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

        console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
        window.localStorage.setItem("AjaxRequestFired", new Date());

        window.clearInterval(sessionCheckIntervalId);
        sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);

        window.clearInterval(timerDisplayIntervalId);
        timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);

        hideTimer();
    }

    function showTimer()
    {
        $('#sessionTimeRemaining').show();
        $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        window.clearInterval(timerDisplayIntervalId);
        badgeTimerId = setInterval(function(){
            $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        }, 1000);
    }

    function hideTimer()
    {
        window.clearInterval(badgeTimerId);
        $('#sessionTimeRemaining').hide();
    }
});
</script>

3.将会话属性配置为配置超时设置备注:在创建会话后配置此属性。您可以实现HttpSessionListener sessionCreated方法,并根据需要设置以下配置。

代码语言:javascript
复制
session.setMaxInactiveInterval(300);

session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);

4.在html下面添加以显示计时器.

注意:如果你擅长CSS,它可以被移动到自动脚本模板页面。因此,您可以避免在每一页中添加此内容。

包括引导或添加您的自定义css。

代码语言:javascript
复制
<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining" 
    onclick="ajaxSessionRefresh()" style="display:none;">
    <i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
     &nbsp; 
     <small>Refresh</small>
     <i class="glyphicon glyphicon-refresh"></i>
</span>

这都是关于一个简单的自动注销实现。您可以从我的github存储库下载工作示例。

使用简单servlet示例的自动输出

使用spring安全java配置示例的自动输出

使用spring安全xml配置示例的自动输出

逻辑解释

案例1:页面加载

这里的逻辑很简单,页面加载设置定时器的间隔为maxInactiveInterval。超时后重定向到登录页面。

案例2:跟踪AJAX调用

现在,考虑到AJAX请求,您可以使用jquery的.ajaxStart()或.ajaxComplete()回调,以便如果触发任何ajax请求,就可以重置间隔。

案例3:跟踪多选项卡/窗口活动

选项卡间通信用于同步每个选项卡的状态。在更改事件上使用localStorage。

所需的限制/改进

  1. 如果最大允许的会话是一个,如果会话是从另一个系统获取的,则AJAX请求将失败。它需要被处理以重定向到登录页面。
  2. 使用ajaxStart()而不是ajaxComplete()在服务器和浏览器之间实现idleTime值的精确同步。

要求

  1. Jquery

比较目前实施的备选办法

  1. 设置http响应中的刷新标头。(不适用于AJAX请求)

代码语言:javascript
复制
response.setHeader("Refresh", "60; URL=login.jsp");
  1. 在中设置元刷新标记(不适用于AJAX请求)
代码语言:javascript
复制
<meta http-equiv="refresh" content="60; url=login.jsp">
  1. 配置活动检查器通过重复的AJAX请求使会话保持活动。跟踪空闲时间并在超时后发出注销请求。 毫无疑问,这是一个好的简单的逻辑。但我只想用墨水记录我的观察结果。
    • 如果每分钟发出2个请求以保持会话活动和50k活动用户,则的性能会影响。每分钟100次请求。
    • 如果打开两个选项卡,一个选项卡正在接收活动,而另一个选项卡没有接收活动,则该选项卡触发注销请求并使会话无效,即使其他选项卡中存在活动。(但可以处理)
    • 强制注销方法它是一个客户端控制在服务器上使会话失效。

票数 3
EN

Stack Overflow用户

发布于 2015-01-05 08:22:10

您可以在web.xml中使用全局超时值:

代码语言:javascript
复制
<session-config>
  <session-timeout>30</session-timeout>
</session-config>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27775651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档