4

在 JPA 应用程序中,我有一个应用程序要执行的场景

列出给定用户有权退出的所有帐户

我有 Account 实体和一个多对多表,其中列出了每个用户对每个帐户的授权——为了实现上述场景,应用程序当前只是内连接两个表——这非常快。

现在,我打算添加一个显式授权层(基于 apache shiro / spring security / other)以将授权相关逻辑与其余代码隔离,但是......

数据库中有大约 10k 个帐户,“普通”用户在所有这些帐户上都被授予“存款”,在其中一半上被授予“查看”权限,在少数人上被授予“提款”权限。

是否有任何安全框架允许有效地实施此方案?

即:他们中的任何一个都能够“装饰”类型为“从帐户 a 中选择 a”(或等效的 SQL)的 JPA 查询,从而在不从数据库加载所有用户授权的情况下获取帐户列表,并且无论如何,而不必检索所有帐户?)

4

3 回答 3

3

看看Apache Shiro

它允许您提取一次用户授权并在会话期间将其缓存。此外,如果所有用户都可以查看所有帐户,那么您不需要显式定义它,这将显着减少开销。

如果您的解决方案需要实时访问处理程序,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 索引的一组简单查询,以构建呈现权限所需的数据结构。

于 2012-09-18T15:25:34.123 回答
0

我希望这是使用 Spring-Security 实现您的要求的可能性之一。

  1. 写自定义,org.springframework.security.acls.PermissionViewAccount,,DepositToAccountWithDrawFromAccount

  2. 编写自定义 org.springframework.security.access.PermissionEvaluatorOverride hasPermission(Authentication userAuthentication,Object accountObject,Object oneOfThePermission)以检查用户是否对 accountObject 具有定义的权限

  3. 在您的自定义评估器中获取对 JPA EntityManager 的引用,并在数据库中使用 user_id、permission_id、account_id 进行交叉检查/验证

  4. 如果用户是“root”,您可以立即返回 true,hasPermission而无需使用 DB 进行验证。

  5. 注释您的服务调用 @PreAuthorize("isAuthenticated() and hasPermission(#accountArgument, 'respectivePermission')")

请参阅链接Permission以获取&的自定义实现PermissionEvaluator

于 2012-05-28T16:03:01.137 回答
0

如果您使用的是 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

于 2012-09-19T15:18:17.190 回答