Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
确保经过身份验证的用户有权访问资源的最佳实践-Spring mvc、Spring Security、Hibernate_Hibernate_Spring Mvc_Spring Security_Acl - Fatal编程技术网

确保经过身份验证的用户有权访问资源的最佳实践-Spring mvc、Spring Security、Hibernate

确保经过身份验证的用户有权访问资源的最佳实践-Spring mvc、Spring Security、Hibernate,hibernate,spring-mvc,spring-security,acl,Hibernate,Spring Mvc,Spring Security,Acl,我们有一个spring mvc rest api,利用spring安全性和hibernate访问MySql数据库 我们配置了一些角色。例如: 标准用户:ROLEA 超级用户:ROLEB 目前,为确保通过认证的用户获得授权访问/更新特定资源,我们执行以下操作: 标识当前经过身份验证的用户: Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String activeLogi

我们有一个spring mvc rest api,利用spring安全性和hibernate访问MySql数据库

我们配置了一些角色。例如:

标准用户:ROLEA

超级用户:ROLEB

目前,为确保通过认证的用户获得授权访问/更新特定资源,我们执行以下操作:

标识当前经过身份验证的用户:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String activeLogin = authentication.getName();
标识与他们尝试访问的实体关联的登录名:

String loginAssociatedToRequestedEntity = fooService.getEntityA(EntityAId).getEntityB().getEntityC().getLogin();
将与给定资源关联的用户与活动登录名进行比较:

if (!loginAssociatedToRequestedEntity.equals(activeLogin)) { 
throw new ForbiddenAccessException();
}
我对此有很多问题,其中包括:

  • 非常浪费……每个实体都必须进行水合/填充。如果要访问的实体离登录名为的表更远,则这可能比上面的示例更糟糕
  • 似乎是一种密码气味(德米特定律)
  • 一个请求可能会更新多个实体。可能需要重复进行与上述类似的检查
我考虑过以下可能的选择:

因此,我的问题是,是否有最佳做法来确保已验证的用户被授权访问某个资源,即阻止他们访问同一角色的另一个用户的资源

如果您能指出一个具体的例子(github),我们将不胜感激


TIA。

您可以使用Spring数据JPA将Spring安全主体信息添加到SQL查询中。例如:


您还可以使用诸如PostgreSQL 9.5、Oracle VPD或SQL Server 2016之类的数据库,这些数据库具有行安全性

,而角色成员身份检查有点反模式(最好对权限或活动进行编码),它们通常用于服务级别访问控制(web请求和方法调用),但是根本不适合在多租户设置中保护实际域对象,例如防止用户访问具有相同角色的另一用户的资源

您检查经过身份验证的登录名是否与特定域对象关联的方法是可行的,但它很麻烦,会将应用程序数据模型与安全数据模型耦合和/或污染,正如您所怀疑的,这不是最佳做法

您已经确定了一些选项:

ApacheShiro提供了一个一致且易于使用的API,支持域对象访问控制,但您负责提供后端“领域”,这意味着您可能必须实现自己的数据存储和/或DAO

Spring安全ACL是Spring的访问控制范例,用于保护域对象。它将安全数据模型与应用程序数据模型分离。通过添加或查找ACL条目,访问控制列表可以轻松授予或检查对域对象的访问权限,但如果您希望高效地查找用户有权访问的所有域对象(例如,在列表中显示这些对象或撤销对它们的访问权),则可能需要编写自己的DAO。此外,您负责维护ACL,因为:

Spring Security不提供任何特殊的集成来自动创建、更新或删除ACL,作为DAO或存储库操作的一部分。相反,您需要为各个域对象编写代码[…]。值得考虑在服务层上使用AOP自动将ACL信息与服务层操作集成

-

最后,如果默认API与您的应用程序模型不兼容(例如,如果您的域对象没有公共
getId()
或不使用与
long
兼容的ID),则必须自定义ACL实现

如果您没有因为提供域对象访问控制而嫁给Spring或Shiro,那么还有另一种选择:

,一个开源Java安全框架(披露:我是维护者和合著者),它提供了一个丰富的API来执行和管理您的授权需求。OACC是一个完整的访问控制框架,具有丰富的API,无需任何DIY实现即可实现细粒度授权的编程和动态建模。它的安全模型有一个完全实现的RDBMS支持的数据存储,API在后台为您管理

OACC的安全模型是基于权限的:它本质上管理资源之间的权限。资源既表示安全域对象,也表示其上的参与者(即主题)。它还提供了高效的查询方法,通过权限查找资源,而无需先加载所有资源,然后过滤掉未经授权的资源。这些方法是对称的,因为您可以找到指定资源具有特定权限集的资源,以及对指定资源具有特定权限集的资源

将下面要授予权限的OACC片段与进行比较:

要检查授权,您可以调用

oacc.assertResourcePermissions(accessorResource, accessedResource, permission);
或者检查

oacc.hasResourcePermissions(accessorResource, accessedResource, permission);
OACC的另一个新特性是创建权限,它不仅控制主体可以创建什么类型的资源,而且还精确地定义在创建新资源后他们将获得什么权限-定义一次后,权限会自动分配给资源创建者,而无需显式API调用


总之,OACC是专门为您的经过身份验证的细粒度授权用例而开发的。

只是想感谢您的回答。我还没有对oacc进行彻底的了解~我确实在入门指南上有点卡住了…请随意在这里或oacc上发布问题,如果您需要任何帮助或澄清,请访问Anks Neil,我们
oacc.hasResourcePermissions(accessorResource, accessedResource, permission);