Java - 高效,数据库感知的实例级授权?

时间:2012-05-28 14:30:08

标签: java jpa spring-security authorization shiro

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

  

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

我有一个帐户实体和一个多对多表,列出了每个用户对每个帐户的授权 - 为了实现上述方案,应用程序当前只是内部加入两个表 - 这非常快。 / p>

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

数据库中有大约10k个帐户,“普通”用户被授予“存款”所有这些帐户,“查看”其中一半,只需“withraw”。

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

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

3 个答案:

答案 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实现您的需求的可能性之一。

  1. 写自定义org.springframework.security.acls.Permission之类的 ViewAccountDepositToAccountWithDrawFromAccount

  2. 写自定义     org.springframework.security.access.PermissionEvaluator覆盖     hasPermission(Authentication userAuthentication,Object accountObject,Object oneOfThePermission)检查用户是否有     accountObject的已定义权限

  3. 参考JPA     自定义评估程序中的EntityManager和DB中的交叉检查/验证     with user_id,permission_id,account_id

  4. 如果用户是“root”,您可以     staight away返回true hasPermission而不验证     DB。

  5. 使用注释来注释您的服务电话     @PreAuthorize("isAuthenticated() and hasPermission(#accountArgument, 'respectivePermission')")
  6. 有关Permission&的自定义实施,请参阅link PermissionEvaluator

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