在JPA应用程序中,我有一个应用程序的场景
列出给定用户有权退出的所有帐户
我有一个帐户实体和一个多对多表,列出了每个用户对每个帐户的授权 - 为了实现上述方案,应用程序当前只是内部加入两个表 - 这非常快。 / p>
现在,我计划添加一个显式授权层(基于apache shiro / spring security / other),将授权相关逻辑与其余代码隔离,但是...
数据库中有大约10k个帐户,“普通”用户被授予“存款”所有这些帐户,“查看”其中一半,只需“withraw”。
是否有任何安全框架可以有效地实施此方案?
即:他们中的任何一个都能够“装饰”“从帐户a中选择一个”(或等效的SQL)类型的JPA查询,从而获得帐户列表,而无需加载来自该帐户的所有用户授权数据库,无论如何,而不必检索所有帐户?)
答案 0 :(得分:3)
查看Apache Shiro。
它允许您拉入用户授权一次并在会话期间缓存它。此外,如果所有用户都可以查看所有ACCOUNTS,那么您不需要明确定义这将显着减少开销。
如果您的解决方案需要实时访问处理程序,Shiro还可以在运行时动态重置权限。
Shiro允许您实现典型的RBAC并定义如下权限:
domain:action:instance
因此,在您的情况下,对于用户来说,权限可能如此:
account:deposit:* // deposit all accounts
account:view:1111
account:view:2222
account:view:3333 // view on these accounts
account:withdraw:5555
account:withdraw:6666 // withdraw on these accounts
在代码中,您可以执行以下操作:
if (SecurityUtils.getSubject().isPermitted("account:withdraw:"+account.getAccountNumber() ) {
// handle withdraw
}
Shiro还有附加抽象的注释驱动权限。
修改的
Shiro权限是最终结果,而不是你开始的地方。我使用了一组表来表示用户到角色和角色到权限的映射以及其他映射到实例的映射。在AuthN之后,它通常是由用户PK索引的一组简单查询,用于构建呈现权限所需的数据结构。
答案 1 :(得分:0)
我希望这是使用Spring-Security实现您的需求的可能性之一。
写自定义org.springframework.security.acls.Permission
之类的
ViewAccount
,DepositToAccount
,WithDrawFromAccount
写自定义
org.springframework.security.access.PermissionEvaluator
覆盖
hasPermission(Authentication userAuthentication,Object
accountObject,Object oneOfThePermission)
检查用户是否有
accountObject的已定义权限
参考JPA 自定义评估程序中的EntityManager和DB中的交叉检查/验证 with user_id,permission_id,account_id
如果用户是“root”,您可以
staight away返回true hasPermission
而不验证
DB。
@PreAuthorize("isAuthenticated() and hasPermission(#accountArgument,
'respectivePermission')")
有关Permission
&的自定义实施,请参阅link PermissionEvaluator
答案 2 :(得分:0)
如果您使用的是EclipseLink,则有一些功能,
一个是@AdditionalCriteria注释,允许将过滤器应用于类的所有查询,
另一个是EclipseLink对Oracle VPD的支持(数据库中的行级安全性),
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing
最后EclipseLink支持可以允许将过滤器附加到任何查询执行的SessionEvents,