当前位置: 代码迷 >> 综合 >> Spring Security RBAC 1.0
  详细解决方案

Spring Security RBAC 1.0

热度:97   发布时间:2024-02-26 11:35:24.0

Spring Security RBAC 1.0

描述

表:5张。用户-角色-权限以及两张关系表。

user 说明
id
username
password
其他
role 说明
id
name
其他
permission 说明
id
name
code
user_role 说明
id
user_id
role_id
role_permission 说明
id
role_id
permission_id
/* Navicat MySQL Data TransferSource Server : MySQL Source Server Version : 80020 Source Host : localhost:3306 Source Database : rbacTarget Server Type : MYSQL Target Server Version : 80020 File Encoding : 65001Date: 2020-10-08 12:45:43 */SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for permission
-- ----------------------------
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (`id` int NOT NULL AUTO_INCREMENT,`permission_name` varchar(255) NOT NULL,`permission_code` varchar(255) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;-- ----------------------------
-- Records of permission
-- ----------------------------
INSERT INTO `permission` VALUES ('1', '用户查看', 'USER_SELECT');
INSERT INTO `permission` VALUES ('2', '用户添加', 'USER_INSERT');
INSERT INTO `permission` VALUES ('3', '用户删除', 'USER_DELETE');
INSERT INTO `permission` VALUES ('4', '用户更新', 'USER_UPDATE');-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (`id` int NOT NULL AUTO_INCREMENT,`role_name` varchar(255) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', '超级管理员');-- ----------------------------
-- Table structure for role_permission
-- ----------------------------
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (`id` int NOT NULL AUTO_INCREMENT,`role_id` int NOT NULL,`permission_id` int NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;-- ----------------------------
-- Records of role_permission
-- ----------------------------
INSERT INTO `role_permission` VALUES ('1', '1', '1');
INSERT INTO `role_permission` VALUES ('2', '1', '2');
INSERT INTO `role_permission` VALUES ('3', '1', '3');-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT COMMENT 'id',`username` varchar(255) NOT NULL,`password` varchar(255) NOT NULL,`locked` tinyint(1) NOT NULL DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'hzk', 'hzk', '0');-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (`id` int NOT NULL AUTO_INCREMENT,`user_id` int NOT NULL,`role_id` int NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('1', '1', '1');

步骤

参考:Spring Security实现RBAC权限管理

1. 配置

数据源+ORM+redis+spring session

# 数据源配置
spring.datasource.username=你的数据库用户名
spring.datasource.password=你的数据库密码
spring.datasource.url=jdbc:mysql://localhost:3306/security_rbac?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Drive
# ORM
mybatis-plus.mapper-locations=classpath:/mapper/*.xml# Hikari 数据源专用配置
# redis配置
# spring-session配置
# thymeleaf配置
spring.thymeleaf.cache=false

2. entity

@Data
public class User implements UserDetails {
    @TableId(type = IdType.ASSIGN_ID)private Long id;private String username;private String password;private Boolean locked;private List<Role> roleList;private List<SimpleGrantedAuthority> permissionList;@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {
    return permissionList;}@Overridepublic boolean isAccountNonExpired() {
    return true;}@Overridepublic boolean isAccountNonLocked() {
    return !locked;}@Overridepublic boolean isCredentialsNonExpired() {
    return true;}@Overridepublic boolean isEnabled() {
    return true;}
}@Data
public class Role {
    @TableId(type = IdType.ASSIGN_ID)private Long id;private String roleName;
}@Data
public class Permission {
    @TableId(type = IdType.ASSIGN_ID)private Long id;private String permissionName;private String permissionCode;
}

3. Repository

@Repository
public interface UserMapper extends BaseMapper<User> {
    User selectByUsername(String username);List<Role> selectRoleListById(Long id);List<Permission> selectPermissionListByRIdList(List<Long> ridList);
}

4. Service

@Service
@Slf4j
public class UserService implements UserDetailsService {
    @Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
    User user = userMapper.selectByUsername(s);if (user == null) {
    throw new UsernameNotFoundException("用户名不存在!");}user.setRoleList(userMapper.selectRoleListById(user.getId()));List<Permission> permissionList = userMapper.selectPermissionListByRIdList(user.getRoleList().stream().map(Role::getId).collect(Collectors.toList()));List<SimpleGrantedAuthority> simpleGrantedAuthorityList = new ArrayList<>(permissionList.size());permissionList.forEach(permission -> simpleGrantedAuthorityList.add(new SimpleGrantedAuthority(permission.getPermissionCode())));user.setPermissionList(simpleGrantedAuthorityList);log.warn("User: {}", user.toString());return user;}
}

5. 配置

登录页面和密码配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Overrideprotected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().and().formLogin().loginPage("/login").failureForwardUrl("/login-error")// .successForwardUrl("/index").permitAll();}@Beanpublic PasswordEncoder passwordEncoder(){
    return NoOpPasswordEncoder.getInstance();}
}

6. 使用

说明:@EnableGlobalMethodSecurity开启方法注解权限判定

说明:访问/user/index页面需要USER_UPDATE权限,db定义超级管理员权限为SELECT|INSERT|DELETE,测试结果:

在这里插入图片描述

@Controller
public class Test {
    @PreAuthorize("hasAuthority(T(com.hzk.app.demo.security.Const.Permission).USER_UPDATE)")@RequestMapping("/user/index")public String userIndex() {
    return "user/index";}
}

参考

Spring Security实现RBAC权限管理

Spring Security 之方法级的安全管控

  相关解决方案