Hur*_*ane 5 acl hibernate spring-mvc spring-security
我们有一个spring mvc rest api,利用spring security和hibernate到MySql db.
我们配置了一些角色.例如:
标准用户: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.
虽然角色成员资格检查在某种程度上是反模式(最好是对权限或活动进行编码),但它们通常用于服务级别访问控制(Web请求和方法调用),但根本不适合保护实际的域对象在多租户设置中,例如,以防止用户访问具有相同角色的另一用户的资源.
检查经过身份验证的登录是否与特定域对象关联的方法是可行的,但是它很麻烦,将应用程序数据模型与安全数据模型耦合和/或污染,并且您认为这不是最佳做法.
您已经确定了一些选项:
Apache Shiro提供了一致且易于使用的API,支持域对象访问控制,但您负责提供后端"领域",这意味着您可能必须实现自己的数据存储和/或DAO.
Spring Security ACL是Spring的安全域对象访问控制范例.它将安全数据模型与应用程序数据模型分离.访问控制列表通过添加或查找ACL条目,可以轻松授予或检查域对象的访问权限,但如果要有效地查找用户有权访问的所有域对象,则可能需要编写自己的DAO(例如,列表中的对象或撤消对它们的访问权限).此外,您有责任维护ACL,因为:
Spring Security不提供任何特殊集成来自动创建,更新或删除ACL,作为DAO或存储库操作的一部分.相反,您需要为各个域对象编写代码[...].值得考虑在服务层使用AOP来自动将ACL信息与服务层操作集成.
最后,如果默认API与您的应用程序模型不兼容,您必须自定义ACL实现(例如,如果您的域对象没有公共getId()或不使用兼容的ID long)
如果您没有与Spring或Shiro结婚以提供域对象访问控制,那么还有另一种选择:
OACC是一个开源Java安全框架(披露:我是维护者和共同作者),它提供了丰富的API来强制和管理您的授权需求.OACC是一个完整的访问控制框架,具有丰富的API,无需任何DIY实现即可实现细粒度授权的编程和动态建模.它为其安全模型提供了完全实现的RDBMS支持的数据存储,API在后台为您管理.
OACC的安全模型是基于权限的:它实质上管理资源之间的权限.资源代表安全域对象及其上的参与者(即主题).它还提供了有效的查询方法,可以通过权限查找资源,而无需先加载所有资源,然后过滤掉未经授权的资源.这些方法是对称的,因为您可以找到指定资源具有特定权限集的资源,以及对指定资源具有特定权限集的资源.
将OACC片段与下面的权限进行比较,使用Spring Security ACL参考中的示例代码:
// get the resource representing the principal that we want to grant permissions to
User accessorUser = Users.findByName("Samantha");
Resource accessorResource = Resources.getInstance(accessorUser.getId());
// get the resource representing the object that we want to grant permissions to
Resource accessedResource = Resources.getInstance(Foos.findById(44).getId());
// Now grant some permissions
Permission permission = ResourcePermissions.getInstance("ADMINISTER");
oacc.grantResourcePermissions(accessorResource, 
                              accessedResource,
                              permission);
要查看授权,您可以致电
oacc.assertResourcePermissions(accessorResource, accessedResource, permission);
或检查的返回值
oacc.hasResourcePermissions(accessorResource, accessedResource, permission);
OACC的另一个新颖特性是创建权限,它不仅可以控制主体可以创建的资源类型,还可以在创建新资源后准确定义它们将获得哪些权限- 定义一次,权限自动分配给资源创建者,无需显式API调用.
总之,OACC是专门针对您的经过身份验证的细粒度授权的用例而开发的.
| 归档时间: | 
 | 
| 查看次数: | 1969 次 | 
| 最近记录: |