在JPA应用程序我有一个场景,其中的应用程序是
列表中的所有账户给予用户被授权从退出
我有帐户实体和许多一对多表,列出哪些核准书每个用户在每个账户 - 执行上述场景中,应用目前只是内部加入了两个表 - 这是相当快的。
现在,我正打算增加一个明确授权层(基于Apache四郎/春季安全/其他)从代码的其余部分隔离授权相关的逻辑,但是...
有一些10K帐户数据库和“平均”的用户将被授予“定金”上所有的人,“意见”对他们的一半,并在短短的几个“withraw”。
是否有任何安全框架,允许有效地实现这个场景?
即:任何人可以“装饰”类型的JPA查询“从帐户中选择一个”(或等价的SQL),从而获得账户列表,而无需从数据库中加载所有用户授权 ,并通过各种手段, 而无需检索所有帐户 ?)
看看阿帕奇四郎 。
它可以让你在用户授权拉一次,并将它缓存为会话的持续时间。 另外,如果所有用户都可以查看所有帐户,那么你就不需要明确定义此这将显著减少开销。
如果您的解决方案需要实时访问处理器四郎有办法在运行时动态地重新设置权限了。
四郎让你实现一个典型的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
}
四郎也有额外的抽象注释驱动的权限。
编辑
四郎权限是最终结果,而不是你开始。 我用一组表示的用户到角色,并与其他映射,比如沿着角色到权限的映射表。 AuthN后它通常是一个简单的用户设置PK建立需要渲染的权限数据结构索引的查询。
我有一个希望,这是实现与Spring的安全您的要求的可能性之一。
编写自定义org.springframework.security.acls.Permission
像ViewAccount
, DepositToAccount
, WithDrawFromAccount
编写自定义org.springframework.security.access.PermissionEvaluator
覆盖hasPermission(Authentication userAuthentication,Object accountObject,Object oneOfThePermission)
以检查用户是否对accountObject定义的权限
获取参考JPA的EntityManager在自定义评估和交叉检查/ DB中的验证与USER_ID,permission_id,ACCOUNT_ID
如果用户是“根”,你可以staight离开返回true hasPermission
没有与DB验证。
- 注释您的服务与调用
@PreAuthorize("isAuthenticated() and hasPermission(#accountArgument, 'respectivePermission')")
请参阅链接的定制实现Permission
和PermissionEvaluator
如果您使用的EclipseLink这是你的一些功能,
一个是@AdditionalCriteria注解,其允许过滤器将被应用于所有查询的一类,
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_additionalcriteria.htm#additionalcriteria
另一个是的EclipseLink的用于Oracle VPD(数据库中的行级安全)支撑,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing
最后的EclipseLink支持SessionEvents可允许过滤器被附加到任何查询执行,
http://www.eclipse.org/eclipselink/api/2.4/org/eclipse/persistence/sessions/SessionEventAdapter.html#preExecuteQuery%28org.eclipse.persistence.sessions.SessionEvent%29