2012-02-21 111 views
2

我与Spring Security的超时与JSF以下问题:JSF春季安全会话超时viewExpiredException

只是如果请求的页面被固定,我定制了sessionmanagement过滤器,以便将用户重定向到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.extraerPagina(请求)”返回请求的页面是这样的:

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(pagSolicitada)”如果帕拉姆是需要被认证的用户(我做的IF检查,考虑其具有属性access="isAuthenticated()"我的XML安全配置文件的拦截-url元素),页面返回true :

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。

任何人知道如何解决这个问题?

预先感谢您。

+0

'它绕过重定向到invalidSessionUrl,但随着会话过期无论如何,然后我得到那个异常试图重新呈现相同的页面。'我不明白这是什么意思。你是说当你重新渲染invalidSessionUrl时,你会得到一个ViewExpiredException? – 2012-02-22 12:09:53

+0

你为什么要编写自己的会话管理过滤器? Spring安全性为您提供了这种功能。只需在Spring xml配置中添加以下内容: ... ' – 2012-02-22 12:14:18

+0

回答第1条评论:'它绕过了重定向到invalidSessionUrl,但无论如何会话过期,然后我得到那个异常,试图重新呈现相同的页面。我的意思是,当我重新呈现浏览器在超时发生时显示的不安全页面时,我得到了“viewExpiredException”。发生这种情况是因为JSF无法构建页面的视图,因为会话已过期。 Spring Security会跳过会话管理过滤器,因为页面不安全(这没问题),但是当JSF尝试重新呈现页面时,它会抛出异常。 – choquero70 2012-02-22 21:48:15

回答

0

最后我解决了它。这是一个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; 
} 

现在的问题是,如果页面有参数,我失去了他们,当我做邮寄到最近创建的视图,但是这另一个与JSF有关的独特问题(PRG模式)。

3

春季安全应该给你匿名访问套页的未认证用户。下面是我的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会寻找一个UserDetails有一个GrantedAuthority属性来确定角色是什么。如果该用户不存在,未经身份验证或未知,则默认为匿名角色。

+0

我知道你在说什么,但那不是我要找的。参考你的场景,如果会话超时,任何用户(无论是否)将被sesion-management-filter重定向到invali-session-url,如果他们请求具有访问属性“IS_AUTHENTICATED_ANONYMOUSLY”的页面(即任何页面谁匹配模式“/*.xhtml”,但不在管理员或应用程序目录中)。但是我想要的不是在这种情况下重定向到invalid-session-url,只是显示我请求的页面,就好像会话没有超时一样(即在这种情况下不应用会话管理过滤器) – choquero70 2012-02-23 21:22:31