芋道框架的权限控制机制

芋道框架支持基本的权限控制机制,其技术层面,是通过SpringSecurity框架来实现的。

下面就从源代码代码中,分析一下芋道是如何做权限控制的。

拿岗位管理的代码示例来说。在文件PostController.java中,看如下代码:

@GetMapping(value = "/get")
@Operation(summary = "获得岗位信息")
@Parameter(name = "id", description = "岗位编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:post:query')")
public CommonResult<PostRespVO> getPost(@RequestParam("id") Long id) {
    PostDO post = postService.getPost(id);
    return success(BeanUtils.toBean(post, PostRespVO.class));
}

这段代码是用于查询岗位列表的。其中,注解@PreAuthorize("@ss.hasPermission('system:post:query')"),表明了,要想调用本方法,需要当前用户具有'system:post:query'权限。

那么,@PreAuthorize("@ss.hasPermission('system:post:query')")这段代码是如何被执行的呢?

答案位于文件YudaoSecurityAutoConfiguration.java中:

@Bean("ss") // 使用 Spring Security 的缩写,方便使用
public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
    return new SecurityFrameworkServiceImpl(permissionApi);
}

可以看到,名称为ss的Bean被注入进来。它是接口SecurityFrameworkService的实现。

而该接口的实现,位于SecurityFrameworkServiceImpl.java。

@AllArgsConstructor
public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {

    private final PermissionApi permissionApi;

    @Override
    public boolean hasPermission(String permission) {
        return hasAnyPermissions(permission);
    }

    @Override
    public boolean hasAnyPermissions(String... permissions) {
        return permissionApi.hasAnyPermissions(getLoginUserId(), permissions);
    }

    @Override
    public boolean hasRole(String role) {
        return hasAnyRoles(role);
    }

    @Override
    public boolean hasAnyRoles(String... roles) {
        return permissionApi.hasAnyRoles(getLoginUserId(), roles);
    }

    @Override
    public boolean hasScope(String scope) {
        return hasAnyScopes(scope);
    }

    @Override
    public boolean hasAnyScopes(String... scope) {
        LoginUser user = SecurityFrameworkUtils.getLoginUser();
        if (user == null) {
            return false;
        }
        return CollUtil.containsAny(user.getScopes(), Arrays.asList(scope));
    }

}

可以看到,其中有一个方法hasPermission,正是上文中提到的注解中的方法。

继续跟踪该方法的实现,最终会落在接口PermissionService的实现类PermissionServiceImpl上:

@Override
public boolean hasAnyPermissions(Long userId, String... permissions) {
    // 如果为空,说明已经有权限
    if (ArrayUtil.isEmpty(permissions)) {
        return true;
    }

    // 获得当前登录的角色。如果为空,说明没有权限
    List<RoleDO> roles = getEnableUserRoleListByUserIdFromCache(userId);
    if (CollUtil.isEmpty(roles)) {
        return false;
    }

    // 情况一:遍历判断每个权限,如果有一满足,说明有权限
    for (String permission : permissions) {
        if (hasAnyPermission(roles, permission)) {
            return true;
        }
    }

    // 情况二:如果是超管,也说明有权限
    return roleService.hasAnySuperAdmin(convertSet(roles, RoleDO::getId));
}

该方法的操作就很明显了,就是通过查询数据库,来判断当前的用户是否拥有对应的权限。

 

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值