验证对实体的访问权限:自定义授权验证注释

时间:2017-06-04 04:02:31

标签: java spring

我的Spring启动应用中有两个实体和两个服务层:UserGroup

以下removeMember方法位于服务层中:

/*Remove member with id userId from group with id groupId, if username is the admin of that group*/
public void removeMember(long groupId, long userId, String username) {
    Group group = loadById(groupId);
    validateAdminAccessToGroup(group, username);
    User user = userService.loadById(userId);
    validateMemberAccessToGroup(group, user.getName());
    if (group.isAdmin(user)) {
        throw new BadRequestException("Group admin cannot delete himself/herself from the group");
    }
    group.removeMember(user);
}

private void validateAdminAccessToGroup(Group group, String username) {
    User user = userService.loadByName(username);
    if (!group.isAdmin(user)) {
        throw new AccessDeniedException("User with id " + user.getId() + " was denied to access group with id " + group.getId() + " as an admin"); 
    }
}

private void validateMemberAccessToGroup(Group group, String username) {
    User user = userService.loadByName(username);
    if (!group.isMember(user)) {
        throw new AccessDeniedException("User with id " + user.getId() + " was denied to access group with id " + group.getId()); 
    }
}

如您所见,只有组的管理员才能从该组中删除成员。

validateAdminAccessToGroup验证用户是否具有访问组的管理员权限,否则会通过错误。 validateMemberAccessToGroup验证用户是组的成员。

我们应该在方法内进行访问检查吗?或使用@PreAuthorize注释?我们可以说这是一个贯穿各领域的问题吗?

2 个答案:

答案 0 :(得分:0)

在我看来,最好处理checkAccessToGroup模型对象中的User,而不是既不传递UserGroupId也不传递AccessLevel,只是处理它在模型内部,将这些值设置为对象成员变量。

然后在Controller层的User实例上调用它。如果您在Service层中调用它,当一个Controller在Service中使用多个方法时,您需要在Service方法中重复调用它,并且最终会将Access Checking部分与Service本身紧密耦合,这将减少服务的可重用性。

答案 1 :(得分:0)

我建议你使用spring security的PreAuthorize类。 Here是一个小例子。您的代码可以从PermissionEvaluator实现中调用,该实现将由spring内部类调用。

因为您需要基于实体/记录的访问,所以您可以实现覆盖hasPermission方法,该方法将以下参数作为输入身份验证(登录用户详细信息),targetId(groupId),targetType(组),权限(删除)。

您需要在控制器/服务方法之上使用以下注释。

@PreAuthorize(" hasPermission(#groupId,' groupd','删除')")

这会将所有不同服务的所有授权逻辑移动到一个类中。