2011-11-23 67 views
1

我有一個頁面:安全JPA在遊戲框架結合

<input type="hidden" name="user.id" value="123" /> 
<input type="text" name="user.name" value="John" /> 

和動作:

public static void save(User user) { 
    user.save(); 
} 

播放加載從數據庫由user.id參數的用戶實體,結合HTTP參數該對象和動作將其保存。

這是確定的像管理可信用戶,但不信任的用戶可以更改HTTP參數:

?user.id=456&user.name=John 

,因此編輯不同的實體。

我檢查用戶是否已更改user.id通過將user.id也放入會話,然後驗證其是否相等。這樣可以正常工作,因爲會話已簽名且無法修改,但我怎樣才能輕鬆地檢查頁面上的多個實體 - 例如在進行批量更新時?或者只是在默認情況下應用程序範圍內?

我不想把20個ID放到會話中,然後檢查每個ID是否等於HTTP參數。我想到了一個解決方案。我會把一個簽名的id作爲一個令牌給每個實體,並在綁定過程中檢查它。你將如何實現這一點?

回答

-1

您可以在控制器中使用checkAuthenticity方法來檢查提交表單的真實性。

在您的服務器代碼中,您還必須檢查用戶是否有權更新這些實體。這可以通過在jpa查詢中向用戶表中添加連接來完成,因此您不僅可以選擇對象標識,還可以選擇連接的用戶

+0

checkAuthenticity僅檢查真實性令牌不id的修改和其旨在防止[CSRF](http://wikipedia.org/wiki/Cross-site_request_forgery)。你的第二個建議會解決它,但它需要更多的編碼。我正在尋找應用範圍廣泛的解決方案。 – Pavel

-1

您必須確保只能通過身份驗證來調用保存用戶。單向玩!允許你這樣做是通過使用@Before註釋。從播放文件的一個例子:

@Before(unless={"login", "authenticate"}) 
static void checkAuthenticated() { 
    if(!session.contains("user")) { 
     login(); 
    } 
} 

user會話屬性將被放在會議只有當用戶已經驗證。只有通過身份驗證的用戶纔可以將HTTP請求發送到您的save()路由。特別注意unlessonly註釋參數。

上面的代碼來自Play中的OpenID example!文檔。我曾經用過這個,迄今爲止這似乎完美。

+1

我已經在應用程序中有身份驗證機制。但這並不能解決問題。用戶可以免費註冊,甚至身份驗證的用戶能夠改變'user.id'參數,因此編輯其他用戶的條目。我試圖找到一個通用的解決方案,您可以一次編輯許多實體並驗證其所有ID。 – Pavel

0

從我明白你想要的是認證和授權。

驗證告訴你用戶是誰,你可以PHK答案做到這一點,或使用secure module

如果要管理授權(什麼用戶可以做,你的情況是什麼對象的用戶可以更新)我建議您查看security-permissions模塊。

它基於安全模塊,但基於drools的規則爲您提供了所需的所有靈活性。

+0

是的,我想是授權用戶發送我回到同一對象(即相同的ID),我給他編輯。當然,我可以在'save()'方法中檢查綁定User對象實際上是用戶允許編輯的對象。但是如果我想要一次綁定並保存實體的完整圖形,我必須遍歷圖並檢查每個實體。每個表單和'save()'方法都需要這個檢查。我正在尋找更通用的解決方案,我會試着用答案來形容它。 – Pavel

+0

將無法​​工作或者是因爲之後的第一個保存調用休眠級聯保存/更新將不會調用pl​​ayframework保存!在這種情況下,您可以使用調用安全權限模塊的hibernate eventListener。 – mericano1

0

我會盡量澄清我的問題結尾提出的解決方案,通常可以解決這個問題。

每個實體將有另一場 - 令牌 - 這是由安全密鑰簽名的實體ID。該令牌不必存儲在數據庫中,但可以即時計算。當編輯頁面被渲染時,它包括例如在__at場:

<input type="hidden" name="user.id" value="123" /> 
<input type="hidden" name="user.__at" value="9e01f3c8...4ccba38b9" /> 
<input type="hidden" name="user.address.id" value="124" /> 
<input type="hidden" name="user.address.__at" value="83df099...4a276fc8" /> 

當這些實體在控制器束縛,再次唱收到的ID,並將其與該__at領域。如果這些簽名值不相同,則表示用戶已更改ID。

我不是一個加密專家,並沒有顯得多麼播放會話簽署,但我想這是類似的。你認爲這種機制可行嗎?