2012-10-30 50 views
0

我正在使用CAS,並且剛剛從3.4.8更新到3.5.1。已經有一千個變化,我認爲我已經處理了最多的。但是,完成時的外部重定向似乎以某種方式被破壞。它只是循環回到login-webflow的開始。這怎麼會發生?Spring webflow externalRedirect重啓相同流程

這是越來越達成的最終狀態:

<!-- The "redirect" end state allows CAS to properly end the workflow while 
    still redirecting the user back to the service required. --> 
    <end-state id="redirectView" 
    view="externalRedirect:${requestScope.response.url}" /> 

我知道這是越來越達成,因爲我在這個方法中設置斷點(的org.springframework.webflow.action.ExternalRedirectAction):

protected Event doExecute(RequestContext context) throws Exception { 
    String resourceUri = (String) this.resourceUri.getValue(context); 
    context.getExternalContext().requestExternalRedirect(resourceUri); 
    return success(); 
} 

如果我檢查在這個方法返回之前的resourceUri的值,我看到這個請求應該被重定向到的URI:

http://mycompany.com:8080/c/portal/login?redirect=%2Fweb%2Fguest%2Fhome&ticket=ST-4-jVOtEEZcy9bXdb4xiV3l-cas 

但是,如果我只是從該斷點運行,而不是被重定向到該頁面,則相同的login-webflow會重新開始。這裏發生了什麼?我應該在哪裏看?任何提示或調試?

--------------- UPDATE ---------------

所以使得0修改代碼後,只是增加一些額外的斷點,它現在按預期工作。我不知道這裏發生了什麼,但我終於找到了實際重定向發生的地方。對於那些有興趣誰,重定向發生在:

org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handleFlowExecutionResult(
     FlowExecutionResult result, ServletExternalContext context, 
     HttpServletRequest request, HttpServletResponse response, FlowHandler handler) 
+0

我有完全相同的問題,上週。 externalRedirect重定向到相同的流量,無論我是作爲redirectView。我改變了我的代碼,並使用一個輸出將url發送給父流,該父流執行了相同的重定向並且工作。很奇怪... – rptmat57

+0

@ rptmat57,出於好奇,你使用的是eclipse,maven(m2e,m2e-wtp)和嵌入式tomcat嗎?我有這個設置很多問題,其中許多存在爲非常奇怪... – Lucas

+0

我使用eclipse,嵌入式tomcat和螞蟻,但沒有maven。我試圖清理tomcat目錄,沒有解決問題。這是一個非常奇怪的問題,因爲我有其他流程使用重定向相同的方式,他們工作正常 – rptmat57

回答

0

我發現一些有用的東西。可能會或可能不適用於您的具體問題。但是如果您將此流程稱爲子流程,則將忽略結束狀態的參數。

但是,如果您只是正常調用此流程,它將執行重定向。你可以做什麼來解決這個問題是使用view-state而不是end-state。但是這會讓你流動和父母流動開放。

2

看起來像這個線程已經休眠了一段時間,但我想給任何可能會出現在未來的人拋出一些信息。以下解釋來自我對CAS 4.0.1的經驗。如果這不適用於舊版本,我會驚呆......

這裏首先要檢查的是您的身份驗證過程是否發生得相對較慢。例如,如果您是通過VPN鏈接或其他方式訪問身份驗證數據庫的開發人員。或者,如果您的身份驗證查詢(和票證存儲)只是相對較慢...

如果這適用於您,我發現CAS中的一個問題,它以一種奇怪的方式與Tomcat進行交互,呈現出上述行爲。

CAS中的問題出現在名爲TerminateWebSessionListener的Web流監聽器中。它似乎是在流程完成後通過快速過期會話來保持內存使用率較低的嘗試。問題是,它很天真地實施。它只是抓取會話並設置2秒的「最大不活動間隔」(默認情況下 - 您可以使用cas-servlet.xml中的TerminateWebSessionListener的timeToDieInSeconds屬性更改此設置。)

與Tomcat的交互如下所示:Tomcat在會話中第一次訪問012999,時首次在一個請求中標記「最後訪問」時間。 然而,每次檢索會話時,都會根據當前時間檢查上次訪問時間,以確定是否已經過了無效時間間隔。

因此,TerminateWebSessionListener期待HttpSession.setMaxInactiveInterval(2)會導致會話在此刻之後失效2秒它真正告訴Tomcat要做的是在當前請求第一次訪問之後2秒使該會話無效。如果您的身份驗證/登錄請求發生時間超過2秒,BOOM! - 下次有人在同一請求中請求會話時,您的會話將失效。不幸的是,這種情況發生在Spring WebFlow本身。所以你在這裏有一個競爭條件。

我打算再想一想,希望能給CAS團隊提供一個解決方案。與此同時,您可以在cas-servlet.xml中禁用TerminateWebSessionListener,或者可以將其timeToDieInSeconds的值提高到您預計會比完成認證請求所需的時間更長的值。也許30秒?這樣做似乎是合理的。它似乎不是一種安全措施,只是一種節省內存的措施。

代碼引用:

  • CAS 4.0.1
    • TerminateWebSessionListener.java:33(sessionEnded()
      • CAS這裏設置會話失效間隔。
  • Tomcat的7.0.55:
    • Request.java:338(session實例變量。)
      • 的Tomcat存儲關於要求其持續時間的會話。
    • Request.java:2899(doGetSession()
      • 如果已經緩存在請求會話早回來沒有access()
    • Request.java:2921(doGetSession()
      • 在請求第一次訪問,會話擡頭,access()調用,並緩存在該請求。

(注:StandardSession.access()只是郵票與會話上次訪問時間System.currentTimeMillis()。)