2013-10-17 43 views
3

我正在開發一個帶有用戶認證和授權的vaadin 7應用程序,使用jaas和應用程序服務器(glassfish)中定義的領域。如何在瀏覽器關閉時關閉vaadin會話但保持http會話?

我有這樣的要求:

  • 用戶可以保持登錄狀態一段時間,因此,他並不需要輸入他的密碼每次。
    我通過設置http會話的會話超時來做到這一點。

  • 該vaadin會話可以鎖定一些資源,並鎖定時,其他會話無法使用此資源。所有鎖定的資源在vaadin會話關閉時釋放。
    我將心跳間隔僅設置爲15秒。

我無法同時獲得兩項要求。 如果我將http會話超時設置爲一分鐘,則在關閉瀏覽器後一分鐘內釋放資源,但用戶下次未通過身份驗證。
如果我將https會話超時設置爲某些日期,則此用戶會被認證,但vaadin會話在3次錯過心跳後不會立即關閉。只有當用戶下次使用相同的http會話時纔會關閉它。

如何達到這兩個要求?

這裏更多信息,與我使用的技術:

  • Glassfish的4
  • web-app的3.1
  • vaadin 7.1.7
  • vaadin-CDI 1.0快照

感謝您的幫助

+0

您能否澄清一下您必須釋放哪種鎖定資源?或者你的意思是一般資源? –

+0

在我的情況下,資源是數據庫中的一些條目。我正在使用我自己的鎖定機制。但關鍵問題的確是如何在瀏覽器關閉後關閉vaadin會話而不會使http會話失效。我現在的解決方法是隻發佈我的鎖定數據庫條目,但保持vaadin sesion。我有一個計時器,每分鐘檢查是否仍然收到心跳。 – raffael

回答

1

有這樣的我在你的問題中含糊不清,但我相信你可以通過使用你自己的close()方法來解決它。你可以創建自己的Vaadin應用類,有一個自定義的close()方法,或者使用TPTApplication並覆蓋其close()方法:

http://vaadin.com/directory#addon/toolkit-productivity-tools:vaadin 

確保當會話被關閉的關閉被調用,做你的在那裏清理。這也將在會話結束時被調用。

如果你不能確保這一點(例如,如果用戶只是關閉窗口,並且你沒有一些JavaScript來處理這個問題),那麼你可以用Vaadin截取窗口,但它會更多一點工作。當用戶試圖關閉該窗口時,您會中斷該過程,通過回調執行您需要執行的操作,然後關閉該窗口。如何做到從vaadin中斷的詳細情況如下所示:

https://vaadin.com/forum/#!/thread/44621/44668 
https://vaadin.com/forum/#!/thread/83207/83206 

回調客戶端而已,所以你將不得不作出對服務器的調用(獲取/通過JavaScript POST),將一起傳遞會話標識到您正在監聽的servlet。然後,servlet將使用傳入的會話ID釋放鎖。

關鍵在於偵聽窗口關閉並能夠適當地響應。

+0

感謝您考慮我的問題,但我認爲這不是我的問題的解決方案。覆蓋UI.close()(我正在使用vaadin 7)函數已經完成,但它沒有被調用,因爲如果http會話沒有超時,vaadin會話沒有關閉。在JavaScript中捕捉瀏覽器關閉事件是可能的,但不能保證它可以在任何情況下工作(例如瀏覽器崩潰)。我想從計時器線程或另一個會話關閉Vaadin會話,但保持http會話屬於關閉的vaadin會話。 – raffael

2

你可能想看看ST Spring Security,尤其是Remember-Me Authentication - 替代我個人使用,而不是試圖實現安全持久登錄自己。

如果你想要去的DIY路徑:

我認爲,試圖將Vaadin從HTTP會話中分離出來是不是個好主意。 Application lifecycle section of the Vaadin book說:

當一個新的客戶端連接時,它創建一個新的用戶會話,由一個VaadinSession實例表示。會話使用存儲在瀏覽器中的cookie進行跟蹤。 ... [Vaadin會話]還通過WrappedSession提供對低層會話對象HttpSession和PortletSession的訪問。

也許你可以通過分離改變你的第一個要求的解決方案(「的用戶可以保持登錄狀態一段時間,因此,他並不需要輸入他的密碼每次。」)至來自http會話的登錄憑證?

你可以存儲一些定時戳記和唯一ID作爲cookie(含到期更新)和customize the VaadinServlet用自己的SessionInitListenerSessionDestroyListener檢查它(和設置),要麼需要登錄憑證或接受來自客戶端的憑據取決於您在服務器上執行的檢查。

+0

感謝您的回答。記住用戶對於身份驗證而言並不是真正的問題。可以使用Spring Security或我自己的cookie和令牌。這會將身份驗證與http會話分開。但我也使用授權(@RolesAllowed註釋),這是我的問題的更難的部分。當然,我也可以採用另一個框架進行授權,但我並不想那麼做。 – raffael

+0

當用戶打開您的應用程序進行自動登錄時,您不能使用身份驗證信息。所以不需要更改授權碼中的任何內容。或者我錯過了你的創作點? – xwoker

+0

在第一次登錄時,我使用用戶名和密碼進行編程登錄(HttpServletRequest.login())。只要http會話存在,這對授權起作用。如果我使用令牌記住用戶,我將不得不根據該令牌進行登錄。我不知道該怎麼做。或者我可以在我的應用程序的某處記住密碼,但我不喜歡這個想法。所以保持http會話一段時間似乎是對我來說最好的主意,但我想關閉vaadin會話。 – raffael

相關問題