jsf-spring安全会话超时viewExpiredException



我在使用JSF的Spring Security中遇到以下超时问题:

我已经自定义了会话管理过滤器,以便在请求的页面安全的情况下(即,仅允许经过身份验证的用户使用),将用户重定向到invalidSessionUrl。我放入Spring Security提供的会话管理过滤器中的自定义代码是:

if (invalidSessionUrl != null) {
     String pagSolicitada = UtilSpringSecurity.extraerPagina(request);
     if ( UtilSpringSecurity.paginaAutenticada(pagSolicitada ) ) {
          request.getSession();
          redirectStrategy.sendRedirect(request, response, invalidSessionUrl);
          return;
     }
     //the requested page doesn't require the user to be authenticated
     //so i just skip this filter and continue with the filter chain
     chain.doFilter(request, response);
     return;
}

方法"UtilSpringSecurity.exterPagina(request)"以这种方式返回请求的页面:

public static String extraerPagina (HttpServletRequest request) {
     String uri = request.getRequestURI().toLowerCase();
     String cPath = request.getContextPath().toLowerCase();
     // uri = cPath + pagina
     int longCPath = cPath.length();
     String pagina = uri.substring(longCPath);
     return pagina;
}

如果参数是一个需要对用户进行身份验证的页面,则方法"UtilSpringSecurity.paginaAutenticada(pagSoliciada)"返回true(我与if进行检查,考虑到我的xml安全配置文件中具有属性access="isAuthenticated()"的截取url元素):

public static boolean paginaAutenticada (String pagina) {
     if (pagina.startsWith("/faces/paginas/administracion/") || pagina.startsWith("/faces/paginas/barco/") ) {
          return true;
     }
     return false;
}

这个解决方案有效,但它只有一个问题:

如果我让浏览器在某个页面上保持空闲,直到会话超时到期,然后我请求相同的页面,那么我会得到一个"viewExpiredException"。这是因为过滤器工作得很好,它绕过了重定向到invalidSessionUrl,但由于会话无论如何都已过期,我在尝试重新呈现同一页面时遇到了异常。

如果我在会话timout过期时请求任何其他不安全的页面,它会正常工作,它会正确重定向到页面,并且我不会得到viewExpiredException。

有人知道怎么解决这个问题吗?

提前谢谢。

Spring安全性应该为未通过身份验证的用户提供对页面集的匿名访问。下面是我如何实现这一点的XML配置的摘录。

<http auto-config="true" access-denied-page="/unauthorized.xhtml" >
    <intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
    <intercept-url pattern="/app/**" access="ROLE_USER,ROLE_ADMIN" />
    <intercept-url pattern="/*.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <form-login login-page="/login.xhtml" login-processing-url="/j_spring_security_check"
        authentication-success-handler-ref="authenticationSuccessBean"
        authentication-failure-handler-ref="authenticationFailureBean"  />
    <session-management invalid-session-url="/login.xhtml" >
    </session-management>
</http>

我本质上使用intercept-url标签来声明某些相对上下文中的页面只能由以下角色访问。您可以看到,匿名用户可以使用web应用程序默认上下文中的所有页面。如果用户未经授权查看页面,则他们将被重定向到access-denied-page

唯一的问题是,用户bean必须实现UserDetails接口,并且具有一个返回实现GrantedAuthority接口的角色bean的属性。Spring将查找具有GrantedAuthority属性的UserDetails,以确定角色是什么。如果该用户不存在、未经身份验证或未知,则默认为匿名角色。

最后我解决了它。这是一个JSF问题,与Spring Security无关。

我以这种方式否决了jsf的restoreView方法:

@Override
public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
     UIViewRoot root = wrapped.restoreView(facesContext, viewId);
     if(root == null) {
          root = createView(facesContext, viewId);
     }
     return root;
}

现在的问题是,如果页面有参数,当我发布到最近创建的视图时,我会丢失它们,但这是另一个不同的问题(PRG模式),再次处理JSF。

相关内容

  • 没有找到相关文章

最新更新