2011-12-14 166 views
16

我在Java身份驗證框架和身份驗證工作流方面沒有太多經驗(只有一些理論知識),所以出於教育目的,我試圖爲我的HTTP創建此類身份驗證應用:使用sessionId或用戶名+密碼的Shiro身份驗證

  1. 客戶的職位登錄+密碼到/login
  2. Shiro通過給定的憑據登錄用戶。服務器返回客戶端他的sessionId
  3. 客戶端請求某種資源/myresource?sessionId=1234567
  4. Shiro通過給定sessionId記錄主題。然後,服務器執行獲取/myresource(使用Shiro管理方法級別訪問權限)的常規工作流程。

基本上我有以下問題:

  1. 我想我沒有必要對HTTP會話的Servlet也不會話。 Shiro擁有自己的會話管理器,足以滿足我的需求。我錯了嗎?
  2. 爲客戶提供真正的sessionId還是應該發送某種sessionToken(它已解析爲服務器端的sessionId)是否是一種好的做法?
  3. 如何使用sessionId(客戶端應在本地存儲)登錄主題?
  4. 在進行這種認證之前,我還需要了解其他任何事情嗎?

在此先感謝。

回答

34

我想我不需要HTTP會話和Servlet會話。 Shiro擁有自己的會話管理器,足以滿足我的需求。我錯了嗎?

不,你說得對。這就是Shiro真棒的原因。從documentation

四郎的會話的支持更簡單使用,也比這兩種[Web容器或EJB有狀態會話Bean]機制的管理,它可在任何應用程序,無論容器。

例如,

Subject currentUser = SecurityUtils.getSubject();  
Session session = currentUser.getSession(); 
session.setAttribute("someKey", someValue); 

the doc報價:getSession calls work in any application, even non-web applications

它是很好的做法,讓客戶真正的sessionId或者我應該送某種sessionToken(這是決心的sessionId在服務器端)?

發送純sessionId是一個壞主意。特別是,如果你通過未加密的網絡發送數據。可以使用類似HTTPS 的東西或使用行 NONCE

而且,請注意,如果通過http/s POST數據,而不是在URL中。

如何使用sessionId(客戶端應在本地存儲)登錄主題?

你的意思是一旦你有會話ID,你怎麼能認證主題?你可以簡單地, 從DOC,

Subject requestSubject = new Subject.Builder().sessionId(sessionId).buildSubject(); 

是否還有其他的事情,我需要做這種身份驗證之前知道嗎?

是的。

  1. 閱讀Shiro's Session Management
  2. 精益約MITM Attack
  3. 關於HTTPSSSL
  4. 一些關於Hash函數thisApache Commons DigestUtils並且可以this

更新

關於該主題驗證部分 - 它是否會使新創建的主題成爲當前驗證的主題?如果不是,我該如何使它成爲「當前」主題?

如果你正在談論new Subject.Builder().sessionId(sessionId).buildSubject(),它不會。我不知道如何將它設置爲當前用戶的線程。 Shiro的JavaDoc說,

[這種方式]返回主題實例不會自動綁定到應用程序(線程)以供進一步使用。也就是說,SecurityUtils.getSubject()不會自動返回與構建器返回的實例相同的實例。如果需要,由框架開發人員來綁定構建的Subject以便繼續使用。

因此,它取決於你如何在當前線程中綁定主題或進一步使用。

如果您擔心的是,在web容器上下文中,它使用簡單的cookie來存儲會話數據。當您通過Shiro過濾器發出請求時,它會附加當前主題以請求其生命週期(當前線程)。當你作爲getSubject()它只是從請求Subject。我發現了一個有趣的線程here

關於nonce部分:如果他向我發送某種散列而不是他的sessionId - 我將無法解碼它以獲取真正的sessionId(以授權他)。我在這裏錯過了什麼嗎?

Nonce部分 - 這是一個痛苦的脖子。現在反思,我認爲做NONCE只是矯枉過正。讓我解釋一些,反正,

  1. 用戶第一次用他的用戶名和密碼登錄。設置userid,nonce(比如UUID)和HASH(sessionID+nonce),在客戶端稱它爲hash1。說,在cookie中。存儲這個nonce在服務器端,可在DB或在地圖作爲user_id <--> nonce,session_id

  2. 在隨後的請求,請確保您回傳useridnonceHASH

  3. 在服務器端,您要做的第一件事是驗證請求。根據客戶端發送的user_id獲取存儲在散列表或數據庫中的sessionIdnonce。創建一個散列HASH(sessionId_from_db + nonce_from_db),將其稱爲hash2。

  4. 現在,如果hash1與hash2匹配,您可以驗證請求,並且由於您已在服務器端存儲了當前sessionId,因此可以使用它。根據請求完成,在cookie和服務器端設置新的隨機數。

如果你經歷了1 - 4,你會意識到你不會需要Shiro進行身份驗證。 (: 所以,我以我的背單詞,杜撰並不在這種情況下,除非你太任性有關安全性的超性能應用

爲什麼MITM攻擊都與我我的客戶(JavaScript的Ajax代碼)取?所以我不認爲我應該關心MITM

我認爲這對你很重要MITM攻擊意味着你的請求/響應通過一臺機器(MITM)鏈接在一起,到你的路由器,如果它是一個未加密的請求,這對MITM來說都是純文本的,他可以看到你所有的請求......並且可能欺騙請求並且可能劫持會話,請讓我找一些例子...... http://michael-coates.blogspot.com/2010/03/man-in-middle-attack-explained.html

+0

感謝您的詳細解答。關於該主題驗證部分 - 它是否會使新創建的「Subject」成爲當前驗證的主題?如果不是,我該如何使它成爲「當前」主題? – bezmax 2011-12-16 09:45:07

相關問題