2011-10-03 232 views
13

我試圖在類型級別上使用@PreAuthorize註釋來保護控制器,並嘗試通過使用不同的@PreAuthorize註釋某些方法來覆蓋該行爲。然而,問題在於Spring首先評估方法註釋(授予訪問權限),然後評估類別註釋(拒絕訪問)。Spring Security的類型級@PreAuthorize不能在方法級別上覆蓋

有什麼方法可以顛倒這個順序嗎?我還沒弄明白。

編輯:

在方法層面上,我要授予訪問權限,只非註冊用戶:

@PreAuthorize("isAnonymous()") 
@RequestMapping(value = "/create", method = RequestMethod.GET) 
public String renderCreateEntity(ModelMap model) { 
    return userService.renderCreateEntity(model); 
} 

然而,對於這個控制器的標準,應該是隻允許充分驗證的用戶:

@Controller 
@RequestMapping(value = "/user") 
@PreAuthorize("isFullyAuthenticated()") 
public class UserController { [...] } 

當調試步進通過應用程序,我看到isAnonymous()首先計算,然後isFullyAuthenticated()從而導致在授予訪問權限並立即拒絕訪問權限。

+0

您使用的是哪個版本的Spring Security? – beny23

+0

一切春天是3.0.5.RELEASE – chzbrgla

回答

11

感謝您的回覆。 但是,答案卻完全不同:)

我把這個放在這裏以防其他人有同樣的問題。

我在@InitBinder帶註釋的方法中註冊了自定義驗證程序。此綁定方法在控制器上請求的方法調用後調用。由於此綁定方法未用@PreAuthorize進行註釋,請求被拒絕。

的解決方案是詮釋這樣的裝訂方法:

@InitBinder 
@PreAuthorize("permitAll") 
public void initBinder(WebDataBinder binder) { 
    binder.setValidator(validator); 
} 

然後,該方法從我的OP評價像預期的要求。

5

問題不在於您需要更改授予和拒絕的順序。問題很簡單,方法級別註釋覆蓋級別註釋。

PrePostAnnotationSecurityMetadataSource Java Doc:

註釋可以對類或方法,和具體方法的註解來指定優先。

該邏輯的具體實現在類PrePostAnnotationSecurityMetadataSource的方法findAnnotation中完成。 (不幸的是,這種方法是私人的。)

所以你可以寫自己的MethodSecurityMetadataSource,如果你看看代碼PrePostAnnotationSecurityMetadataSource,你會看到它是多麼容易。

但是最後一個警告:結束:困難的任務不是重寫方法,困難的任務是將新的MethodSecurityMetadataSource「注入」到安全系統中。我相信你不能用Spring安全性命名空間配置來完成它,所以你需要通過顯式的bean聲明來替換spring安全性命名空間。

+0

我其實_WANT_方法級別註釋覆蓋類級別註釋。但是方法級別註釋首先被評估,而第二級別是級別級別,因此類級別註釋實際上會覆蓋方法的註釋。我會編輯一些例子到我的問題。 – chzbrgla

+0

從我的測試中,這不再是真的。如果您有類級別和方法級別的安全註釋(@Secured或@PreAuthorized),它們都會運行。如果方法級別註釋更具限制性,這就好了。如果限制較少,則不起作用。我最終將我的限制較少的方法分解到另一個控制器中。 –

相關問題