2013-07-01 108 views
10

我正在尝试使用Apache Shiro框架来保护我的Web应用程序(UI基于Vaadin 6)。通过Shiro网站上的所有示例,并搜索了几个小时,但我无法找到一个干净的方式来处理以下要求。如何使用Apache Shiro处理分层角色/权限?

假设应用程序是一种项目管理工具,用户正在创建活动,属于公司层次结构中的特定部门。每个用户可以在多个部门工作,并且在每个部门中具有不同的安全角色。例如:

 
Department A  - User is 'Manager' here 
Department B 
    Department C  - User is 'Admin' here 
    Department D 

用户是在部门A “用户管理器”是在部ç 用户“管理”也应该继承“管理”为部d(这是系的C祖先)的作用。

所以,基本的权限检查(假设我要查看属于一些部门的活动)将是:

  1. 检查活动用户试图查看所属部门用户有一定作用;
  2. 检查用户是否需要基于他的角色在此部门的许可。

我目前停留在理解如何实施不仅仅是“系统广角”,而是“在这个特定部门的作用”的概念。

如何将上面的示例转换为像“activity:view:123”这样的权限字符串?我将如何检查业务逻辑中的权限?

另一个疑问是Shiro的实现,我想使用一些开箱即用的解决方案将最小的努力提供我自己的实现。但是,Shiro的内置实现似乎只适用于简单情况。是否有任何复杂的授权实施示例(可以涵盖上述情况)?

回答

3

只是想描述一下我对这个问题的解决方法,这对某些人可能是有用的。我觉得这可能不是最佳的,所以仍然欢迎任何有关更清洁实施的建议。

假设我需要确保采取以下行动:

  • 活动:编辑
  • 活动:鉴于

而且我也需要确保权限是不是全系统,而是依赖关于我在特定部门的角色。我所做的是在我的Realm中为用户明确添加了“依赖于部门”的权限。例(见层次结构在后):

  • DEP_A:活动:鉴于
  • DEP_C:活动:鉴于
  • DEP_C:活动:编辑

每次我要检查行动针对某些活动是否允许,我创建了一个要检查的权限列表。例如:

活动A属于D部门,我想“查看”它。权限检查将是:

  • DEP_D:活动:鉴于
  • DEP_C:活动:鉴于
  • DEP_B:活动:鉴于

如果我是小编在部门C,我会有'DEP_C:活动:查看'权限,因此 检查将通过。这就允许在公司结构层次结构中实现权利继承。

这里是我的服务类的代码snipplet负责权限检查:

@Override 
    public void checkIfOperationPermitted(SecurityOperation operation, 
     Object object) 
    { 
     final Subject currentUser = SecurityUtils.getSubject(); 

     if(currentUser.isPermitted(
     SecurityOperation.SYSTEM_ADMIN.getPermissionString()) || 
     currentUser.hasRole("admin")) 
     { 
     // no need to check anything else, 
     // admin is system wide role. 
     return; 
     } 

     if(object instanceof Activity) 
     { 
     // Activity permissions fully depends on organization and 
     // product hierarchies. PermissionResolver is just a class 
     // which generates list of permission strings based on 
     // department activity is belonging to. 
     Activity a = (Activity) object; 
     List<String> permissionsToCheck = 
      permissionResolver.resolveHierarchicalPermissions(operation, a); 
     boolean permitted = false; 
     for(String permission: permissionsToCheck) 
     { 
      if(currentUser.isPermitted(permission)) 
      { 
       permitted = true; 
       break; 
      } 
     } 
     if(!permitted) 
     { 
      throw new UnauthorizedException("Access denied"); 
     } 
     } 
     else 
     { 
     // Check for system wide permissions 
     currentUser.checkPermission(operation.getPermissionString()); 
     } 
    } 

我在想另一种方法是增加所有这些权限的用户在我的领域,但他拒绝透露该公司自层次结构可以在一般包含N层 - 这大大增加了特定用户权限列表中的重复(内存使用)。

相关问题