springboot实现ACL+RBAC权限体系

news2024/11/26 13:57:01

本文基于web系统的权限控制非常重要的前提下,从ALC和RBAC权限控制两个方面,介绍如何在springboot项目中实现一个完整的权限体系。

源码下载 :https://gitee.com/skyblue0678/springboot-demo

序章

一个后台管理系统,基本都有一套自己的权限体系,权限体系分两种分别是基于控制列表的权限,和基于角色的权限。

基于控制列表的权限,也叫ACL认证体系。就是每个权限,你可以理解为每一个controller方法都有一个自己的用户列表,只有存在于该列表的用户可以访问这个方法。

而基于角色的权限,就是每个用户有自己的角色,而角色拥有多个controller方法的访问权限,用户和角色,角色和接口都是多对多的关系。

ACL: Access Control List

简介:以前非常盛行的一种权限设计,它的核心主要在于用户和权限直接挂钩。

优点:简单易用、开发便捷。

缺点:用户是直接和权限挂钩,导致了在授予权限的时候的复杂性,比较分散,不太易于管理。

例子:常见的文件系统,直接给用户家权限。比如给用户加读写的权限。

RBAC:Role Based Access Control

简介:基于角色的访问控制系统。权限是与角色进行相关联,用户通过成为适当的角色成员从而得到这些角色的权限。

优点:简化了用户和权限的管理,用过对用户进行分类,使得其与角色和权限关联起来。

缺点:开发起来相对于ACL复杂。

例子:基于REAC模型的权限验证框架与应用Apache Shiro、Spring security。

第一章 ACL的权限控制

表结构设计

上面说了,ACL是权限和用户直接挂钩,我们需要设计数据库表来存储用户和权限信息。以下是简化的表结构设计:

sql:

DROP TABLE IF EXISTS `acl`;
CREATE TABLE `acl` (
  `id` int NOT NULL,
  `user_id` int DEFAULT NULL,
  `permission_id` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `permission_id` (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
  `id` int NOT NULL AUTO_INCREMENT,
  `permission` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

初始化数据:

-- 插入用户数据  
INSERT INTO User (id, username, password) VALUES (1, 'jack', '1');  
INSERT INTO User (id, username, password) VALUES (2, 'rose', '1');  
  
-- 插入权限数据  
INSERT INTO Permission (id, permission) VALUES (1, 'device:list');  
INSERT INTO Permission (id, permission) VALUES (2, 'device:add');  

  
-- 插入ACL数据  
INSERT INTO ACL (id, user_id, permission_id) VALUES (1, 1, 1);  
INSERT INTO ACL (id, user_id, permission_id) VALUES (2, 2, 2);

ACL权限设计代码

有了用户,权限,acl三张表后,就根据matisplus将对应的增删改查功能实现。

Mapper

public interface UserMapper extends BaseMapper<User> {
}

public interface PermissionMapper extends BaseMapper<Permission> {
}

public interface AclMapper extends BaseMapper<Acl> {
}

Service

public interface UserService  extends IService<User> {
    User getByUsername(String username);
}


public interface PermissionService extends IService<Permission> {
    List<Permission> findByIds(Set<Integer> permIds);
}

public interface AclService extends IService<Acl> {

    List<Permission> findByUserId(Integer id);
}

impl

@Service
@Slf4j
public class UserServiceImpl  extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public User getByUsername(String username) {
        return baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserName,username));
    }
}


@Service
@Slf4j
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
    @Override
    public List<Permission> findByIds(Set<Integer> permIds) {
        return baseMapper.selectBatchIds(permIds);
    }
}

@Service
@Slf4j
public class AclServiceImpl extends ServiceImpl<AclMapper, Acl> implements AclService {

    @Resource
    PermissionService permissionService;

    @Override
    public List<Permission> findByUserId(Integer id) {
        List<Acl> acls = baseMapper.selectList(new LambdaQueryWrapper<Acl>().eq(Acl::getUserId, id));
        Set<Integer> permIds = acls.stream().map(Acl::getPermissionId).collect(Collectors.toSet());
        return permissionService.findByIds(permIds);
    }
}

最后是在login里面获取用户的权限

@GetMapping("/acl/login")
public String loginAcl(String username,String password){
    User user = userService.getByUsername(username);
    if(Objects.nonNull(user)){
        if(!user.getPwd().equals(password)){
            return "密码错误!";
        }
        //根据用户获取ACL权限列表
        List<Permission> permissionList = aclService.findByUserId(user.getId());
        return permissionList.toString();
    }else {
        return "用户名不存在";
    }
}

测试:

浏览器访问: http://localhost:8080/acl/login?username=jack&password=1

[Permission(id=1, permission=device:list)]

这个例子中,我们通过用户登录,获取了对应的权限列表,后续的章节中,我们会做真实的权限校验。

第二章 RBAC的权限控制

RBAC比ACL就是多了一个角色的概念,用户是拥有角色的,角色对应具体的权限,所以控制起来更加的灵活。

表结构设计

以下是简化的表结构设计:

sql

DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` int NOT NULL AUTO_INCREMENT,
  `role_name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `role` VALUES ('1', '设备管理员');

DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
  `id` int NOT NULL AUTO_INCREMENT,
  `role_id` int DEFAULT NULL,
  `permission_id` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `role_permission` VALUES ('1', '1', '1');

DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int DEFAULT NULL,
  `role_id` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `user_role` VALUES ('1', '1', '1');

RBAC的登录方法

@GetMapping("/rbac/login")
public String loginRbac(String username,String password){
    User user = userService.getByUsername(username);
    if(Objects.nonNull(user)){
        if(!user.getPwd().equals(password)){
            return "密码错误!";
        }
        //根据用户获取ACL权限列表
        List<Permission> permissionList = userService.findByUserRole(user.getId());
        return permissionList.toString();
    }else {
        return "用户名不存在";
    }
}

根据用户角色查询权限

@Override
public List<Permission> findByUserRole(Integer id) {
    return baseMapper.findByUserRole(id);
}

mapper

public interface UserMapper extends BaseMapper<User> {
    List<Permission> findByUserRole(@Param("id") Integer id);
}

xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.it.demo.mapper.UserMapper">


    <select id="findByUserRole" resultType="com.it.demo.entity.Permission">
        SELECT
            e.*
        FROM
            USER a
                LEFT JOIN user_role b ON a.id = b.user_id
                LEFT JOIN role c ON b.role_id = c.id
                LEFT JOIN role_permission d ON c.id = d.role_id
                LEFT JOIN permission e ON d.permission_id = e.id
        WHERE
            a.id = #{id}
    </select>
</mapper>

访问:http://localhost:8080/rbac/login?username=jack&password=1

[Permission(id=1, permission=device:list)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1049250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

更好用的Mybatis Plus:Mybatis Flex(下)

前言 上篇文章讲了 Mybaits Flex 的基础用法&#xff0c;这次讲一下 Mybatis Flex 的进阶用法&#xff0c;包含了一些 Mybatis Flex 核心的一些功能。&#xff08;以下简称 MF&#xff09; 逻辑删除 上篇文章讲到了 Column 注解&#xff0c;其中有个属性为 isLogicDelete &…

2023软工作业(一)——计算器

班级班级社区作业要求软件工程实践第一次作业-CSDN社区作业目标完成一个具有可视化界面的科学计算器参考文献Fyne 目录 作业要求 项目源码地址 作业目标 0. 界面及功能展示 1. PSP表格 2. 解题思路描述 3. 核心代码 4. 设计与实现过程 5. 程序性能改进 6. 单元测试展…

向华为学习:制订一份分工明确、能够落地的产品GTM行动计划表

昨天华研荟介绍了新产品上市的GTM的定义、GTM这个岗位&#xff08;角色&#xff09;的主要工作以及新产品的GTM要回答好的四个问题&#xff08;Why、What、How、Where&#xff09;&#xff0c;帮助大家初步理解了让产品上市更成功的GTM流程。 如我昨天在文章中所讲到的&#x…

ACM MM 2023 | 基于去中心化表征的人体姿态估计方法

01. 前言 北京邮电大学与EVOL创新团队共同提出人体姿态估计方法DecenterNet&#xff0c;用于在提高在拥挤场景下人体姿态估计的准确度。该方法引入了一种去中心化的姿势表征方法&#xff0c;使得网络在纠缠区域/拥挤区域中将更加稳健地表达人体姿态。该方法还提出了一个解耦的…

LeetCode【577. 员工奖金】

表&#xff1a;Employee ---------------------- | Column Name | Type | ---------------------- | empId | int | | name | varchar | | supervisor | int | | salary | int | ---------------------- empId 是该表中具有唯一值的列。 该…

BFS专题7 多终点迷宫问题

题目&#xff1a; 样例&#xff1a; 输入 3 3 0 0 0 1 0 0 0 1 0 输出 0 1 2 -1 2 3 -1 -1 4 思路&#xff1a; 单纯的 BFS 迷宫问题&#xff0c;只是标记一下每个点的 step&#xff0c;注意初始化答案数组都为 -1. 代码详解如下&#xff1a; #include <iostream> #…

Windows下使用pybind11教程(python调用C++代码)

1. 下载pybind11 gittub中下载&#xff0c;pybind下载后解压 2. C生成库文件 2.1.VS新建空白工程&#xff0c;工程名随意起 - 2.2更改目标文件名和配置类型 - 2.3更改目标文件拓展名 2.4添加include路径和库路径 包含目录中添加刚刚下载好的pybind的include路径以及pyhon的…

C#的HALCON引擎调用_传入参数输出结果实现流程

1、在Halcon的开发环境里面写处理流程。 此案例使用HALCON自带图片&#xff1a; read_image (Image, printer_chip/printer_chip_01) 读入图片之后&#xff0c;做处理流程&#xff1a; *图像处理流程&#xff1a; *传入图像变量&#xff0c;阈值最小值&#xff0c;最大值。…

软件测试/测试开发丨利用人工智能自动找Bug

点此获取更多相关资料 简介 在程序员编程的过程中&#xff0c;产生Bug是一件平常的事情&#xff0c;以前在编码的过程中提前找出Bug&#xff0c;需要通过单元测试、CodeReview等各种方式。 当今&#xff0c;人工智能技术的发展给软件开发和测试带来了许多机会。利用人工智能…

聊聊并发编程——多线程之AQS

目录 队列同步器&#xff08;AQS&#xff09; 独占锁示例 AQS之同步队列结构 解析AQS实现 队列同步器&#xff08;AQS&#xff09; 队列同步器AbstractQueuedSynchronizer&#xff08;以下简称同步器&#xff09;&#xff0c;是用来构建锁或者其他同步组 件的基础框架&…

TikTok美国市场爆品:美牙仪一周售出3.36万单,GMV近百万刀

最近一周&#xff0c;超店有数洞察到TikTok Shop美国市场出现一款爆火美牙仪&#xff0c;该款商品售价为31.95美金&#xff0c;佣金比率为25%&#xff0c;一周内销量达3.36万单&#xff0c;GMV近94万美金。自今年7月底上架以来在TikTok上关联视频播放量高达140W&#xff0c;属于…

企业长假期间如何应对突发业务需求?提前部署远程控制为上策

没有人想在长假期间加班&#xff0c;包括管理层也是一样的。但客观来说&#xff0c;很多企业的业务在假期中也是不能中断的&#xff0c;如果业务线遇到紧急需要处理的问题&#xff0c;有没有办法不用长途跋涉跑回公司一趟呢&#xff1f;远程控制现在就是很多企业的选择。 时值…

静态住宅代理是什么?为什么要选择它?

静态住宅代理是互联网服务提供商(ISP)分配的住宅ISP代理。正如名称“静态”所指&#xff0c;他的IP永久不会变化。在当今的数字时代&#xff0c;数据安全、隐私和在线访问已变得至关重要&#xff0c;具有无限带宽的静态住宅代理提供了出色的解决方案。下面给大家具体介绍。 一、…

Django实战项目-学习任务系统-需求说明

一&#xff0c;需求说明   在我最近的阅读中&#xff0c;我深深被一些关于智能或系统的小说吸引。这些小说的主角意外获得某种神秘的智能或系统&#xff0c;然后通过完成系统发布的各种任务&#xff0c;逐渐提升自己的知识和能力。即使是普通的屌丝&#xff0c;也能在系统的管…

win10环境mysql8.10免安装版本配置

MySQL :: Download MySQL Community Server 下载免安装包 解压到相应目录。 以管理员身份启动cmd net start mysql 服务无法启动。 运行mysqld --initialize --console初始化 生成临时密码 验证临时密码并登录测试 mysql -u root -p出错 启动 net start mysql 运行phpmya…

Leetcode684. 冗余连接

Every day a Leetcode 题目来源&#xff1a;684. 冗余连接 解法1&#xff1a;并查集 因为需要判断是否两个节点被重复连通&#xff0c;所以我们可以使用并查集来解决此类问题。 代码&#xff1a; /** lc appleetcode.cn id684 langcpp** [684] 冗余连接*/// lc codestart…

PID温度控制器,全球市场总体规模,前17大厂商排名及市场份额

PID温度控制器全球市场总体规模 PID温度控制器是一种常用的温度控制设备&#xff0c;能够通过使用比例、积分和微分控制算法来实现精确的温度调节。它可以监测和调整温度&#xff0c;保持设定的温度稳定。PID代表比例、积分和微分&#xff0c;比例&#xff08;P&#xff09;控…

【Verilog教程】6.7 Verilog流水线

关键词&#xff1a;流水线&#xff0c;乘法器 硬件描述语言的一个突出优点就是指令执行的并行性。多条语句能够在相同时钟周期内并行处理多个信号数据。 但是当数据串行输入时&#xff0c;指令执行的并行性并不能体现出其优势。而且很多时候有些计算并不能在一个或两个时钟周期…

linux权限机制,

目录 用户与组,id,passwd 查看登录用户whomi,who,w 创建用户 useradd 修改用户信息usermod 删除指定用户userdel 组 ​编辑创建修改删除组groupadd groupmod groupdel 权限 ls-l 修改文件所属用户&#xff0c;所属组 chown,chgrp(change group) 修改权限 chmod 默认权…

针对http接口进行测试,使用Jmeter工具实现

前言&#xff1a; 本文主要针对http接口进行测试&#xff0c;使用Jmeter工具实现。 Jmter工具设计之初是用于做性能测试的&#xff0c;它在实现对各种接口的调用方面已经做的比较成熟&#xff0c;因此&#xff0c;本次直接使用Jmeter工具来完成对Http接口的测试。 一、开发接口…