0


我们有一个 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 过滤器来使会话无效?
我非常感谢您对此的任何帮助和反馈,因为它是高度优先的。

4

1 回答 1

0

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

根本原因是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"/>

希望它会有所帮助。

于 2017-05-30T02:02:29.133 回答