网站开发服务转包合同,参考消息电子版手机版,wordpress写入权限,开发商虚假宣传怎么赔偿本文基于web系统的权限控制非常重要的前提下#xff0c;从ALC和RBAC权限控制两个方面#xff0c;介绍如何在springboot项目中实现一个完整的权限体系。 源码下载 #xff1a;https://gitee.com/skyblue0678/springboot-demo
序章
一个后台管理系统#xff0c;基本都有一套…本文基于web系统的权限控制非常重要的前提下从ALC和RBAC权限控制两个方面介绍如何在springboot项目中实现一个完整的权限体系。 源码下载 https://gitee.com/skyblue0678/springboot-demo
序章
一个后台管理系统基本都有一套自己的权限体系权限体系分两种分别是基于控制列表的权限和基于角色的权限。
基于控制列表的权限也叫ACL认证体系。就是每个权限你可以理解为每一个controller方法都有一个自己的用户列表只有存在于该列表的用户可以访问这个方法。
而基于角色的权限就是每个用户有自己的角色而角色拥有多个controller方法的访问权限用户和角色角色和接口都是多对多的关系。
ACL Access Control List
简介以前非常盛行的一种权限设计它的核心主要在于用户和权限直接挂钩。
优点简单易用、开发便捷。
缺点用户是直接和权限挂钩导致了在授予权限的时候的复杂性比较分散不太易于管理。
例子常见的文件系统直接给用户家权限。比如给用户加读写的权限。
RBACRole 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)
) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_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)
) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_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)
) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_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 BaseMapperUser {
}public interface PermissionMapper extends BaseMapperPermission {
}public interface AclMapper extends BaseMapperAcl {
}Service
public interface UserService extends IServiceUser {User getByUsername(String username);
}public interface PermissionService extends IServicePermission {ListPermission findByIds(SetInteger permIds);
}public interface AclService extends IServiceAcl {ListPermission findByUserId(Integer id);
}
impl
Service
Slf4j
public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService {Overridepublic User getByUsername(String username) {return baseMapper.selectOne(new LambdaQueryWrapperUser().eq(User::getUserName,username));}
}Service
Slf4j
public class PermissionServiceImpl extends ServiceImplPermissionMapper, Permission implements PermissionService {Overridepublic ListPermission findByIds(SetInteger permIds) {return baseMapper.selectBatchIds(permIds);}
}Service
Slf4j
public class AclServiceImpl extends ServiceImplAclMapper, Acl implements AclService {ResourcePermissionService permissionService;Overridepublic ListPermission findByUserId(Integer id) {ListAcl acls baseMapper.selectList(new LambdaQueryWrapperAcl().eq(Acl::getUserId, id));SetInteger 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权限列表ListPermission permissionList aclService.findByUserId(user.getId());return permissionList.toString();}else {return 用户名不存在;}
}测试
浏览器访问 http://localhost:8080/acl/login?usernamejackpassword1
[Permission(id1, permissiondevice: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)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_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)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_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)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_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权限列表ListPermission permissionList userService.findByUserRole(user.getId());return permissionList.toString();}else {return 用户名不存在;}
}根据用户角色查询权限
Override
public ListPermission findByUserRole(Integer id) {return baseMapper.findByUserRole(id);
}mapper
public interface UserMapper extends BaseMapperUser {ListPermission findByUserRole(Param(id) Integer id);
}
xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.it.demo.mapper.UserMapperselect idfindByUserRole resultTypecom.it.demo.entity.PermissionSELECTe.*FROMUSER aLEFT JOIN user_role b ON a.id b.user_idLEFT JOIN role c ON b.role_id c.idLEFT JOIN role_permission d ON c.id d.role_idLEFT JOIN permission e ON d.permission_id e.idWHEREa.id #{id}/select
/mapper
访问http://localhost:8080/rbac/login?usernamejackpassword1
[Permission(id1, permissiondevice:list)]