RBAC实现授权

本文介绍了基于角色和资源的访问控制(RBAC)的区别,着重讲解了资源访问控制的优点以及在SpringScrutty中的应用。通过实例说明了如何查询用户权限和实现细粒度授权,包括SQL拼接查询语句的使用。
摘要由CSDN通过智能技术生成

RBAC分为两种方式:

基于角色的访问控制(Role-Based Access Control)

基于资源的访问控制(Resource-Based Access Control)

角色的访问控制(Role-Based Access Control)是按角色进行授权,比如:主体的角色为总经理可以查询企业运营报表,查询员工工资信息等,访问控制流程如下:

根据上图中的判断逻辑,授权代码可表示如下:

Java
if(主体.hasRole("总经理角色id")){
查询工资
}

 当需要修改角色的权限时就需要修改授权的相关代码,系统可扩展性差。

基于资源的访问控制(Resource-Based Access

Control)是按资源(或权限)进行授权,比如:用户必须具有查询工资权限才可以查询员工工资信息等,访问控制流程如下:

根据上图中的判断,授权代码可以表示为:

Java
if(主体.hasPermission("查询工资权限标识")){
    查询工资
}

优点:系统设计时定义好查询工资的权限标识,即使查询工资所需要的角色变化为总经理和部门经理也不需要修改授权代码,系统可扩展性强。

我们项目使用基于资源的访问控制:

这个主要就是通过下面注解来实现的

 这个注解使用条件就是我们的微服务·必须使用springscruty 也就是要引入相关的坐标。

使用这个注解的原理是什么呢,当我们携带令牌访问微服务的上面资源的时候,我们springscruty就会比较我们我们注解中的授权信息是否在令牌中的授权信息列表中,如果不在那么就会报错。

权限系统的实现过程。

权限系统的数据模型

 

说明如下:

xc_user:用户表,存储了系统用户信息,用户类型包括:学生、老师、管理员等

xc_role:角色表,存储了系统的角色信息,学生、老师、教学管理员、系统管理员等。

xc_user_role:用户角色表,一个用户可拥有多个角色,一个角色可被多个用户所拥有

xc_menu:模块表,记录了菜单及菜单下的权限

xc_permission:角色权限表,一个角色可拥有多个权限,一个权限可被多个角色所拥有

 

查询用户所拥有的权限

例子:

SELECT * FROM xc_menu WHERE id IN(
    SELECT menu_id FROM xc_permission WHERE role_id IN(
        SELECT role_id FROM xc_user_role WHERE user_id = '49'
    )
)

 在资源上面加上注解,指定权限

 在生成令牌之前,对权限信息进行赋值

Java
//查询用户身份
public UserDetails getUserPrincipal(XcUserExt user){
    String password = user.getPassword();
    //查询用户权限
    List<XcMenu> xcMenus = menuMapper.selectPermissionByUserId(user.getId());
    List<String> permissions = new ArrayList<>();
    if(xcMenus.size()<=0){
        //用户权限,如果不加则报Cannot pass a null GrantedAuthority collection
        permissions.add("p1");
    }else{
        xcMenus.forEach(menu->{
            permissions.add(menu.getCode());
        });
    }
    //将用户权限放在XcUserExt中
    user.setPermissions(permissions);

    //为了安全在令牌中不放密码
    user.setPassword(null);
    //将user对象转json
    String userString = JSON.toJSONString(user);
    String[] authorities = permissions.toArray(new String[0]);
    UserDetails userDetails = User.withUsername(userString).password(password).authorities(authorities).build();
    return userDetails;

}

 对于细粒度的权限控制我们只能自己实现了。如下

我的课程,教学机构只允许查询本教学机构下的课程信息。

我的选课,学生只允许查询自己所选课。

如何实现细粒度授权?

细粒度授权涉及到不同的业务逻辑,通常在service层实现,根据不同的用户进行校验,根据不同的参数查询不同的数据或操作不同的数据。

实现方式之一 使用sql拼装查询语句

 LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();
 //机构id
 queryWrapper.eq(CourseBase::getCompanyId,companyId);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值