在Spring Data存储库中使用@PreAuthorize

时间:2012-12-06 22:57:12

标签: spring-security spring-data spring-data-jpa

我试图通过在我的存储库界面上使用@PreAuthorize注释来保护Spring-Data存储库(因为大多数方法都是继承的),因此所有方法都是安全的。 结果是我的接口中包含的任何自定义方法都获得Spring-Data接口继承的所有方法的安全性。 在扩展超接口的简单组件接口上应用相同的东西将正常工作。 我不确定这是Spring-Security还是Spring-Data问题。我希望得到一些帮助来解决这个问题。 可以在http://forum.springsource.org/showthread.php?133083-Using-PreAuthorize-on-SpringData-repositories下载工作服务设置和非工作Spring-Data存储库的单元测试示例。失败的testSuperRepositoryWithUser应该获得AccessDeniedException,但@PreAuthorize注释不适用于JpaRepository接口。

2 个答案:

答案 0 :(得分: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 :(得分:0)

您可以在@PreAuthorize接口的所有方法上应用Repository或类似的注释,方法是将其应用于接口,而不是方法。

@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> {}