2012-02-21 424 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