只想描述我对这个问题的解决方案,这可能对某人有用。我觉得这可能不是最佳的,所以仍然愿意接受任何关于更清洁实施的建议。
假设我需要确保以下操作:
而且我还需要确保权限不是系统范围的,而是取决于我在特定部门的角色。我所做的是为我的领域中的用户明确添加了“部门相关”权限。示例(参见帖子中的层次结构):
- DEP_A:活动:视图
- DEP_C:活动:视图
- DEP_C:活动:编辑
每次我想检查是否允许对某些活动采取行动时,我都会创建一个要检查的权限列表。例子:
活动 A 属于 D 部门,我想“查看”它。检查权限为:
- DEP_D:活动:视图
- DEP_C:活动:视图
- DEP_B:活动:视图
如果我是 C 部门的管理员,我将拥有“DEP_C:activity:view”权限,因此检查将通过。这允许在公司结构层次结构中实现权限继承。
这是我的服务类中负责权限检查的代码片段:
@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 层 - 这大大增加了特定用户权限列表中的重复(内存使用)。