2013-10-04 14 views
1

我見過很多問題,要求如何處理安全方案,都有解決方法註釋(即@PreAuthorize("hasRole('ROLE_USER')"))或使用切點。什麼是正確的方法來拒絕訪問特定資源在春天MVC +安全

但是,如果用戶訪問資源直到資源從數據存儲中讀取,那麼資源未知?讓我們考慮可以訪問一組客戶的用戶,其他客戶端可以在/customers/{id}找到。用戶只有在被授予閱讀帳戶權限的情況下才被允許訪問,同樣他們也必須有權訪問相同的端點以創建POST

一種方法是:

@RequestMapping(value = "/customers/{id}", method = RequestMethod.GET) 
public ModelAndView customerPage(String id, HttpServletRequest req, Principal principal) { 
    if (!req.isUserInRole("ROLE_ADMIN") && !cs.accessGranted(id, principal.getName())) { 
     throw new AccessDeniedException("You do not have access to view this custoemr."); 
    } 
    Customer cust = cs.getCustomer(id); 
    if (cust == null) { 
     throw new ResourceNotFoundException("Customer does not exist!"); 
    } 
    ModelAndView mov = new ModelAndView("customers/info"); 
    mov.addObject("customer", cust); 
    return mov; 
} 

我想知道如果這是正確的做法,但。

UPDATE:致電accessGranted的意思是讓id作爲我錯過的論點。

回答

1

有一種方法可以繼續使用@PreAuthorize註釋。您可以直接從規劃環境地政司表達致電豆:

@PreAuthorize("hasRole('ROLE_USER') and [email protected](#principal.getName())") 
public ModelAndView customerPage(String id, HttpServletRequest req, Principal principal) { 

@cs指豆ID =「CS」在你的應用程序上下文somwhere聲明。稍後,您可以通過刪除Principal principal方法參數並直接在SpEL中獲取用戶名來簡化它。

如果你發現自己使用這個技巧,那麼經常會檢查出Spring Security ACL模塊。

+0

這是一個很好的方法,我實際上更喜歡SpEL來引用服務的實例成員,這樣我就不需要命名我的服務bean,儘管我認爲你的解決方案是最靈活的。 –

+0

好主意。你如何獲得參考成員?使用'#root'變量? –

+0

我認爲它實際上是'#this',但我相信你不能訪問成員,但可以訪問訪問器。我沒有嘗試過,但是'@PreAuthorize(「hasRole('ROLE_ADMIN')or!#this.accessGranted(#id,#principal.getName())」)''。我認爲'#principal'在spring安全表達式中可以自動使用。我從來沒有真正使用SpEL,即使我把它全部打開,我也無法使註釋工作,他們似乎被忽略了。 –

0

我最喜歡的方法是在一個方法上使用@Secured註釋,該方法需要一個表示執行該方法所需的角色的字符串數組。我喜歡這種方法,因爲您不僅限於將安全性僅限於URL模式。例如,您可以將此添加到您的Service類中的一個方法中,並且現在使用該服務的任何Controller都受到保護。

另一種常見的方法是在Spring Security XML文件中包含URL過濾器。我忘記了確切的語法,但您基本上設置了匹配URL的過濾器,並指出需要哪些角色。

+0

儘管它不保護特定的域對象,但它將保護方法或URI。我需要例如用戶'jdoe'訪問'/ customers/123',但'/ customers/234'不應該是可訪問的。它是一個安全性ACL,用於確定哪些用戶可以訪問哪些客戶。 –

+0

我不認爲這是一個開箱即用的解決方案。我認爲你需要開發自定義代碼來處理這個問題。 – CodeChimp

相關問題