会话的部分响应过期

Posted

技术标签:

【中文标题】会话的部分响应过期【英文标题】:partial-response on session expire 【发布时间】:2016-01-07 13:08:36 【问题描述】:

我们有一个 JSF 2.0、Primefaces 5.0、Spring Security 3.2.3.RELEASE 应用程序。 为了处理会话超时,我使用 primefaces idleMonitor 和 p:dialog & javascript 来显示倒计时弹出窗口并将它们重定向回登录页面。 我还实现了一个自定义 CacheControlPhaseListener,这样页面就不会被缓存。我在 CacheControlPhaseListener 的响应头中设置了 no-cache。

<lifecycle><phase-listener id="nocache">com..filter.CacheControlPhaseListener</phase-listener></lifecycle>

我的 web.xml 中也配置了错误处理:

 <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/error.jsf</location></error-page>

我还实现了一个扩展 ViewHandlerWrapper 的 ViewExpiredHandler

@Override
public UIViewRoot restoreView(FacesContext ctx, String viewId)

    UIViewRoot viewRoot = super.restoreView(ctx, viewId);
    try
    
        if (viewRoot == null)
        
            viewRoot = super.createView(ctx, viewId);
            ctx.setViewRoot(viewRoot);
        
    
    catch (Exception e)
    
        e.printStackTrace();
    
    return viewRoot;

我仍然遇到的问题是: 1。当会话在空闲页面(例如搜索页面)上过期并且如果在页面上触发了某些 ajax 操作,即使我注销,当我导航回页面(例如登录->主页->搜索页面)时。我看到一个部分响应的 xml 错误:

<partial-response><changes><update id="blGridId"><table id="blGridId" style="width:100%;"> <tbody> <tr> <td><div id="blTableId" class="ui-datatable ui-widget ui-datatable-scrollable ui-datatable-resizable"><div id="sublTableId_paginator_top" class="ui-paginator ui-paginator-top ui-widget-header ui-corner-top" role="navigation"><span class="ui-paginator-prev ui-state-default ui-corner-all ui-state-disabled"><span class="ui-icon ui-icon-seek-prev">p</span></span><span class="ui-paginator-next ui-state-default ui-corner-all ui-state-disabled"><span class="ui-icon ui-icon-seek-next">p</span></span></div><div class="ui-widget-header ui-datatable-scrollable-header"><div class="ui-datatable-scrollable-header-box"><table role="grid"><thead id="blTableId_head"><tr role="row"><th id="blTableId:j_idt101" class="ui-state-default ui-resizable-column" role="columnheader" style="width:34px; #width:37px;"><span class="ui-column-title"><span style="word-wrap: break-word;white-space: normal;">Client </span></span></th><th id="blTableId:j_idt104" class="ui-state-default

2.如果我点击浏览器刷新,它会加载回页面,我可以继续操作。 请让我知道除了上述之外我还需要做什么来解决部分响应错误。我是否需要添加一个 servlet 过滤器来使会话无效? 我非常感谢对此的任何帮助和反馈,因为它是高度优先的。

【问题讨论】:

@BalusC:我不太清楚***.com/questions/28317891/… 中给出的分辨率 - 我们需要在登录后重定向到默认页面吗? 使用相同的设置。 IE。告诉 Spring 安全性在登录后始终重定向到给定的目标 URL。 好的,谢谢,我会试试的。 @BalusC :我检查了,我们已经配置了一个默认目标 URL。下面是 Spring 配置: springframework.org/schema/beans" xmlns:sec="springframework.org/schema/security" xmlns:xsi="w3.org/2001/XMLSchema-instance" xsi:schemaLocation="springframework.org/schema/beans"> .... ` 但是还是出现错误 【参考方案1】:

会话过期时我遇到了同样的问题。我认为为时已晚,但也许会对像我这样有问题的其他人有所帮助。

根本原因是 Spring Security 在重定向客户端进行身份验证之前保存了最后一个请求。之后,当用户访问最后一个请求的页面时,Spring Security 会尝试再次执行请求。不幸的是,请求是 ajax/partial 并且它的视图已经过期 -> 部分 xml 内容被返回。

摆脱这个问题的简单方法是删除 Spring Security 的保存行为。 SavedRequestAwareAuthenticationSuccessHandler 类用于处理此类行为。配置为:

<bean id="authenticationFilter"  class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
        p:authenticationManager-ref="authenticationManager"
        p:authenticationFailureHandler-ref="authenticationFailureHandler"
        p:authenticationSuccessHandler-ref="authenticationSuccessHandler"
        p:usernameParameter="username"
        p:passwordParameter="password">
    </bean>
... 

<bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"
        p:defaultTargetUrl="/"
        p:alwaysUseDefaultTargetUrl="true"/>

希望对您有所帮助。

【讨论】:

以上是关于会话的部分响应过期的主要内容,如果未能解决你的问题,请参考以下文章

当会话 cookie 在 Laravel 中过期时重新加载站点

使用protect_from_forgery时,Rails 403 会话响应过期

防止会话在非活动用户的 PHP 会话中过期

无法获得在 Angular 2 代码中映射的正确 http 响应

MongoDB 学习笔记之 TTL索引,部分索引和文本索引

在基于 Spring 的 Web 应用程序中处理会话过期事件