繁体   English   中英

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

[英]Java – efficient, database-aware instance-level authorization?

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

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

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

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

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

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

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

看看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索引的一组简单查询,用于构建呈现权限所需的数据结构。

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

  1. 编写自定义org.springframework.security.acls.PermissionViewAccountDepositToAccountWithDrawFromAccount

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

  3. 在自定义求值程序中获取对JPA EntityManager的引用,并在DB中使用user_id,permission_id,account_id进行交叉检查/验证

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

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

请参阅PermissionPermissionEvaluator自定义实现的链接

如果您正在使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM