2012-12-06 69 views
0

我試圖通過在我的存儲庫接口上使用@PreAuthorize批註來保護Spring-Data存儲庫(因爲大多數方法都是繼承的),以便所有方法都得到保護。 結果是,包含在我的接口中的任何自定義方法都通過Spring-Data接口繼承的所有方法獲得安全性。 在擴展超級接口的簡單組件接口上應用相同的東西將可以正常工作。 我不確定這是Spring-Security還是Spring-Data問題。我希望得到一些幫助解決這個問題。 可以在http://forum.springsource.org/showthread.php?133083-Using-PreAuthorize-on-SpringData-repositories下載有關工作服務設置和非工作Spring數據存儲庫單元測試的示例。失敗的testSuperRepositoryWithUser應該得到一個AccessDeniedException,但@PreAuthorize註解不適用於JpaRepository接口。在SpringData存儲庫上使用@PreAuthorize

+0

當在xml配置中使用protect-pointcut啓用安全性時,同樣的問題也適用。 –

+0

您是否有「正常」情況(Repository1.findAll()和Repository2.findAll()具有不同的允許角色列表)還是簡化的(所有存儲庫的所有findAll()方法都具有相同的允許角色列表)? –

回答

1

默認情況下,spring將JDK代理包裝到bean中。在這種情況下,註釋只能用於接口方法。所以你需要一些更強大的代理(CGlib或AspectJ)。我不確定它會如何解決你的問題。你可以嘗試CGLIB:

<security:global-method-security ... proxy-target-class="true" /> 

對於AspectJ的:

<security:global-method-security ... mode="aspectj" /> 

在這兩種情況下,你將需要額外的庫和額外的配置。 有關更多詳細信息,請參閱AOP Proxies

從架構的角度來看,安全註釋的最佳位置在於您的服務方法。考慮以下情況:您有ServiceA.methodA()和ServiceB.methodB()。他們使用RepositoryC.methodC()。您的客戶需要methodA()和methodB()的不同安全權限。如果您的安全層應用於存儲庫,那將是不可能的。因此,只需將您的安全註釋應用於服務即可,完全沒有問題。

+1

我曾嘗試cglib,但它不會工作。 AspectJ不適用於具體類。同意體系結構的觀點,但在我的情況下,我想公開存儲庫如果一個OSGI服務,並控制誰(用戶或服務)調用它。如果沒有直接保護存儲庫方法的能力,我必須將它與一個服務綁定在一起,該服務將公開和保護相同的方法,這是一個小小的不便之處,因爲我必須複製在服務IF上爲我生成的方法spring-data。 –

0

您可以通過將@PreAuthorize或類似的註釋應用於接口而不是方法來應用接口的所有方法。

@PreAuthorize("hasRole('ROLE_SUPERUSER')") 
public interface PersonnelRepository extends PagingAndSortingRepository<Person, Long>{} 

您也可以提供一個基礎庫,其他人繼承這將確保遺傳資源庫的方法的註釋。

@NoRepositoryBean 
@RepositoryRestResource() 
@PreAuthorize("hasAuthority('ROLE_USER')") 
public interface BaseRepository<T, ID extends Serializable> 
    extends PagingAndSortingRepository<T, ID>{} 

現在這個存儲庫在它的所有方法上也具有相同的安全性。

public interface FooRepo extends BaseRepository <Foo, Long> {}