Search in sources :

Example 1 with AuthorizationException

use of org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException in project doorkeeper by limbo-world.

the class PolicyChecker method check.

/**
 * 校验策略是否通过
 *
 * @param policy 策略
 * @param params 校验参数 k=v
 * @return
 */
public Intention check(PolicyVO policy, List<String> params) {
    PolicyType policyType = PolicyType.parse(policy.getType());
    if (policyType == null) {
        throw new AuthorizationException("解析policy类型失败,类型" + policy.getType());
    }
    // 用户没启用的情况
    Intention intention = Intention.parse(policy.getIntention());
    if (!user.getIsEnabled()) {
        return reverseIntentionIfNotPassed(intention, false);
    }
    if (!policy.getIsEnabled()) {
        return reverseIntentionIfNotPassed(intention, false);
    }
    // 根据策略类型判断逻辑
    boolean checkPassed;
    try {
        switch(policyType) {
            case ROLE:
                checkPassed = doRoleCheck(policy);
                break;
            case PARAM:
                checkPassed = doParamCheck(policy, params);
                break;
            case USER:
                checkPassed = doUserCheck(policy);
                break;
            case GROUP:
                checkPassed = doGroupCheck(policy);
                break;
            case COMBINE:
            case TIME:
            default:
                throw new AuthorizationException("不支持的策略类型:" + policyType);
        }
    } catch (Exception e) {
        log.error("策略校验失败 " + JacksonUtil.toJSONString(policy));
        throw e;
    }
    return reverseIntentionIfNotPassed(intention, checkPassed);
}
Also used : PolicyType(org.limbo.doorkeeper.api.constants.PolicyType) AuthorizationException(org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException) Intention(org.limbo.doorkeeper.api.constants.Intention) AuthorizationException(org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException)

Example 2 with AuthorizationException

use of org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException in project doorkeeper by limbo-world.

the class ResourceChecker method check.

/**
 * 进行权限校验,是否有资格访问
 *
 * @param userId     用户id
 * @param checkParam 用于获取资源的参数
 * @return
 */
public ResourceCheckResult check(Long userId, ResourceCheckParam checkParam) {
    ClientPO client = getClient(checkParam.getClientId());
    UserPO user = getUser(userId);
    if (!user.getIsEnabled()) {
        return emptyResult();
    }
    try {
        // 找到待检测的启用资源
        List<ResourceVO> resources = findResources(client.getRealmId(), client.getClientId(), checkParam);
        if (CollectionUtils.isEmpty(resources)) {
            return emptyResult();
        }
        // 找到资源权限关系
        List<PermissionResourcePO> permissionResources = permissionResourceMapper.selectList(Wrappers.<PermissionResourcePO>lambdaQuery().in(PermissionResourcePO::getResourceId, resources.stream().map(ResourceVO::getResourceId).collect(Collectors.toList())));
        if (CollectionUtils.isEmpty(permissionResources)) {
            return checkResourceRefuseResult(resources);
        }
        Set<Long> permissionIds = new HashSet<>();
        Map<Long, List<Long>> resourcePermissionMap = new HashMap<>();
        for (PermissionResourcePO permissionResource : permissionResources) {
            permissionIds.add(permissionResource.getPermissionId());
            if (!resourcePermissionMap.containsKey(permissionResource.getResourceId())) {
                resourcePermissionMap.put(permissionResource.getResourceId(), new ArrayList<>());
            }
            resourcePermissionMap.get(permissionResource.getResourceId()).add(permissionResource.getPermissionId());
        }
        // 查询权限
        List<PermissionVO> allPermissions = getPermissions(client.getRealmId(), client.getClientId(), new ArrayList<>(permissionIds));
        if (CollectionUtils.isEmpty(allPermissions)) {
            return checkResourceRefuseResult(resources);
        }
        // 获取策略ID
        Map<Long, PermissionVO> permissionMap = new HashMap<>();
        Set<Long> policyIds = new HashSet<>();
        for (PermissionVO permission : allPermissions) {
            if (Logic.parse(permission.getLogic()) == null) {
                throw new IllegalArgumentException("无法解析权限的策略,permission=" + permission);
            }
            permissionMap.put(permission.getPermissionId(), permission);
            if (CollectionUtils.isNotEmpty(permission.getPolicies())) {
                policyIds.addAll(permission.getPolicies().stream().map(PermissionPolicyVO::getPolicyId).collect(Collectors.toList()));
            }
        }
        if (CollectionUtils.isEmpty(policyIds)) {
            return checkResourceRefuseResult(resources);
        }
        // 获取策略
        List<PolicyVO> allPolicies = policyDao.getVOSByPolicyIds(client.getRealmId(), client.getClientId(), new ArrayList<>(policyIds), true);
        if (CollectionUtils.isEmpty(allPolicies)) {
            return checkResourceRefuseResult(resources);
        }
        Map<Long, PolicyVO> policyMap = allPolicies.stream().collect(Collectors.toMap(PolicyVO::getPolicyId, policyVO -> policyVO));
        // 获取策略校验器
        PolicyChecker checker = policyCheckerFactory.newPolicyChecker(user);
        List<ResourceVO> result = new ArrayList<>();
        ASSIGNER_ITER: for (ResourceVO resource : resources) {
            // 获取资源权限ID
            List<Long> resourcePermissionIds = resourcePermissionMap.get(resource.getResourceId());
            if (CollectionUtils.isEmpty(resourcePermissionIds)) {
                if (refuseWhenUnauthorized) {
                    continue;
                } else {
                    result.add(resource);
                }
            }
            // 获取资源权限
            List<PermissionVO> permissionVOS = new ArrayList<>();
            for (Long permissionId : resourcePermissionIds) {
                if (permissionMap.containsKey(permissionId)) {
                    permissionVOS.add(permissionMap.get(permissionId));
                }
            }
            if (CollectionUtils.isEmpty(permissionVOS)) {
                if (refuseWhenUnauthorized) {
                    continue;
                } else {
                    result.add(resource);
                }
            }
            // 对Permission的Intention进行分组
            Map<Intention, Set<PermissionVO>> intentGroupedPerms = permissionVOS.stream().collect(Collectors.groupingBy(permissionVO -> Intention.parse(permissionVO.getIntention()), Collectors.mapping(Function.identity(), Collectors.toSet())));
            // 先检测 REFUSE 的权限,如果存在一个 REFUSE 的权限校验通过,则此资源约束被看作拒绝
            Set<PermissionVO> refusedPerms = intentGroupedPerms.getOrDefault(Intention.REFUSE, new HashSet<>());
            for (PermissionVO permission : refusedPerms) {
                if (checkPermissionLogic(checker, checkParam, permission, policyMap)) {
                    continue ASSIGNER_ITER;
                }
            }
            // 再检测 ALLOW 的权限
            Set<PermissionVO> allowedPerms = intentGroupedPerms.getOrDefault(Intention.ALLOW, new HashSet<>());
            for (PermissionVO permission : allowedPerms) {
                if (checkPermissionLogic(checker, checkParam, permission, policyMap)) {
                    result.add(resource);
                    continue ASSIGNER_ITER;
                }
            }
        }
        return new ResourceCheckResult(result);
    } catch (Exception e) {
        log.error("鉴权校验失败", e);
        throw new AuthorizationException(e.getMessage());
    }
}
Also used : PolicyVO(org.limbo.doorkeeper.api.model.vo.policy.PolicyVO) java.util(java.util) PolicyDao(org.limbo.doorkeeper.server.infrastructure.dao.PolicyDao) PermissionVO(org.limbo.doorkeeper.api.model.vo.PermissionVO) Intention(org.limbo.doorkeeper.api.constants.Intention) Autowired(org.springframework.beans.factory.annotation.Autowired) ResourceCheckResult(org.limbo.doorkeeper.api.model.vo.check.ResourceCheckResult) Function(java.util.function.Function) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ResourceVO(org.limbo.doorkeeper.api.model.vo.ResourceVO) ResourceQueryParam(org.limbo.doorkeeper.api.model.param.query.ResourceQueryParam) org.limbo.doorkeeper.server.infrastructure.mapper(org.limbo.doorkeeper.server.infrastructure.mapper) org.limbo.doorkeeper.server.infrastructure.po(org.limbo.doorkeeper.server.infrastructure.po) DoorkeeperConstants(org.limbo.doorkeeper.api.constants.DoorkeeperConstants) PermissionPolicyVO(org.limbo.doorkeeper.api.model.vo.PermissionPolicyVO) Wrappers(com.baomidou.mybatisplus.core.toolkit.Wrappers) PolicyCheckerParam(org.limbo.doorkeeper.api.model.param.query.PolicyCheckerParam) Collectors(java.util.stream.Collectors) PermissionQueryParam(org.limbo.doorkeeper.api.model.param.query.PermissionQueryParam) Slf4j(lombok.extern.slf4j.Slf4j) Component(org.springframework.stereotype.Component) ResourceCheckParam(org.limbo.doorkeeper.api.model.param.query.ResourceCheckParam) UriMethod(org.limbo.doorkeeper.api.constants.UriMethod) Logic(org.limbo.doorkeeper.api.constants.Logic) AuthorizationException(org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException) AuthorizationException(org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException) ResourceCheckResult(org.limbo.doorkeeper.api.model.vo.check.ResourceCheckResult) PermissionPolicyVO(org.limbo.doorkeeper.api.model.vo.PermissionPolicyVO) AuthorizationException(org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException) PolicyVO(org.limbo.doorkeeper.api.model.vo.policy.PolicyVO) PermissionPolicyVO(org.limbo.doorkeeper.api.model.vo.PermissionPolicyVO) ResourceVO(org.limbo.doorkeeper.api.model.vo.ResourceVO) PermissionVO(org.limbo.doorkeeper.api.model.vo.PermissionVO)

Example 3 with AuthorizationException

use of org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException in project doorkeeper by limbo-world.

the class RoleChecker method check.

/**
 * 获取用户拥有的角色
 */
public RoleCheckResult check(Long userId, RoleCheckParam checkParam) {
    RoleCheckResult result = new RoleCheckResult();
    result.setRoles(new ArrayList<>());
    UserPO user = userMapper.selectById(userId);
    if (user == null) {
        throw new AuthorizationException("无法找到用户,Id=" + userId);
    }
    if (!user.getIsEnabled()) {
        return result;
    }
    // 根据查询条件获取角色id
    List<RolePO> roles = roleMapper.selectList(Wrappers.<RolePO>lambdaQuery().select(RolePO::getRoleId).eq(RolePO::getRealmId, user.getRealmId()).eq(RolePO::getIsEnabled, true).in(CollectionUtils.isNotEmpty(checkParam.getRoleIds()), RolePO::getRoleId, checkParam.getRoleIds()).eq(checkParam.getClientId() != null, RolePO::getClientId, checkParam.getClientId()).eq(StringUtils.isNotBlank(checkParam.getName()), RolePO::getName, checkParam.getName()).like(StringUtils.isNotBlank(checkParam.getDimName()), RolePO::getName, checkParam.getDimName()).in(CollectionUtils.isNotEmpty(checkParam.getNames()), RolePO::getName, checkParam.getNames()));
    if (CollectionUtils.isEmpty(roles)) {
        return result;
    }
    Set<Long> roleIds = roles.stream().map(RolePO::getRoleId).collect(Collectors.toSet());
    // 获取用户角色
    List<UserRolePO> userRoles = userRoleMapper.selectList(Wrappers.<UserRolePO>lambdaQuery().eq(UserRolePO::getUserId, userId).in(UserRolePO::getRoleId, roleIds));
    if (CollectionUtils.isEmpty(userRoles)) {
        userRoles = new ArrayList<>();
    }
    // 用户拥有的角色ID
    Set<Long> userOwnedRoleIds = userRoles.stream().map(UserRolePO::getRoleId).collect(Collectors.toSet());
    // 用户所在用户组的角色
    List<Long> userGroupRoleIds = getUserGroupRoleIds(userId, user.getRealmId(), roleIds);
    userOwnedRoleIds.addAll(userGroupRoleIds);
    if (CollectionUtils.isEmpty(userOwnedRoleIds)) {
        return result;
    }
    roles = roleMapper.selectBatchIds(userOwnedRoleIds);
    if (CollectionUtils.isEmpty(roles)) {
        return result;
    }
    result.setRoles(EnhancedBeanUtils.createAndCopyList(roles, RoleVO.class));
    return result;
}
Also used : RoleVO(org.limbo.doorkeeper.api.model.vo.RoleVO) GroupRoleVO(org.limbo.doorkeeper.api.model.vo.GroupRoleVO) AuthorizationException(org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException) RoleCheckResult(org.limbo.doorkeeper.api.model.vo.check.RoleCheckResult)

Example 4 with AuthorizationException

use of org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException in project doorkeeper by limbo-world.

the class GroupChecker method check.

/**
 * 获取用户所在用户组
 */
public GroupCheckResult check(Long userId, GroupCheckParam checkParam) {
    GroupCheckResult result = new GroupCheckResult();
    result.setGroups(new ArrayList<>());
    UserPO user = userMapper.selectById(userId);
    if (user == null) {
        throw new AuthorizationException("无法找到用户,Id=" + userId);
    }
    if (!user.getIsEnabled()) {
        return result;
    }
    user.setPassword(null);
    // 获取用户用户组
    List<GroupUserPO> userGroups = groupUserMapper.selectList(Wrappers.<GroupUserPO>lambdaQuery().eq(GroupUserPO::getUserId, userId).in(CollectionUtils.isNotEmpty(checkParam.getGroupIds()), GroupUserPO::getGroupId, checkParam.getGroupIds()));
    if (CollectionUtils.isEmpty(userGroups)) {
        return result;
    }
    // 获取用户组
    List<Long> groupIds = userGroups.stream().map(GroupUserPO::getGroupId).collect(Collectors.toList());
    List<GroupPO> groups = groupMapper.selectList(Wrappers.<GroupPO>lambdaQuery().eq(GroupPO::getRealmId, user.getRealmId()).in(GroupPO::getGroupId, groupIds).eq(StringUtils.isNotBlank(checkParam.getName()), GroupPO::getName, checkParam.getName()).like(StringUtils.isNotBlank(checkParam.getDimName()), GroupPO::getName, checkParam.getDimName()).in(CollectionUtils.isNotEmpty(checkParam.getNames()), GroupPO::getName, checkParam.getNames()));
    if (CollectionUtils.isEmpty(groups)) {
        return result;
    }
    // 合并数据
    List<GroupVO> groupVOS = EnhancedBeanUtils.createAndCopyList(groups, GroupVO.class);
    for (GroupVO groupVO : groupVOS) {
        for (GroupUserPO userGroup : userGroups) {
            if (groupVO.getGroupId().equals(userGroup.getGroupId())) {
                groupVO.setGroupUserId(userGroup.getGroupUserId());
                groupVO.setUserId(userGroup.getUserId());
                groupVO.setExtend(userGroup.getExtend());
            }
        }
    }
    result.setGroups(groupVOS);
    return result;
}
Also used : AuthorizationException(org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException) GroupCheckResult(org.limbo.doorkeeper.api.model.vo.check.GroupCheckResult) GroupUserPO(org.limbo.doorkeeper.server.infrastructure.po.GroupUserPO) UserPO(org.limbo.doorkeeper.server.infrastructure.po.UserPO) GroupUserPO(org.limbo.doorkeeper.server.infrastructure.po.GroupUserPO) GroupPO(org.limbo.doorkeeper.server.infrastructure.po.GroupPO) GroupVO(org.limbo.doorkeeper.api.model.vo.GroupVO)

Aggregations

AuthorizationException (org.limbo.doorkeeper.server.infrastructure.exception.AuthorizationException)4 Intention (org.limbo.doorkeeper.api.constants.Intention)2 Wrappers (com.baomidou.mybatisplus.core.toolkit.Wrappers)1 java.util (java.util)1 Function (java.util.function.Function)1 Collectors (java.util.stream.Collectors)1 Slf4j (lombok.extern.slf4j.Slf4j)1 CollectionUtils (org.apache.commons.collections4.CollectionUtils)1 DoorkeeperConstants (org.limbo.doorkeeper.api.constants.DoorkeeperConstants)1 Logic (org.limbo.doorkeeper.api.constants.Logic)1 PolicyType (org.limbo.doorkeeper.api.constants.PolicyType)1 UriMethod (org.limbo.doorkeeper.api.constants.UriMethod)1 PermissionQueryParam (org.limbo.doorkeeper.api.model.param.query.PermissionQueryParam)1 PolicyCheckerParam (org.limbo.doorkeeper.api.model.param.query.PolicyCheckerParam)1 ResourceCheckParam (org.limbo.doorkeeper.api.model.param.query.ResourceCheckParam)1 ResourceQueryParam (org.limbo.doorkeeper.api.model.param.query.ResourceQueryParam)1 GroupRoleVO (org.limbo.doorkeeper.api.model.vo.GroupRoleVO)1 GroupVO (org.limbo.doorkeeper.api.model.vo.GroupVO)1 PermissionPolicyVO (org.limbo.doorkeeper.api.model.vo.PermissionPolicyVO)1 PermissionVO (org.limbo.doorkeeper.api.model.vo.PermissionVO)1