Spring Security 权限管理

2020-12-27 22:30

阅读:684

概述

权限是大部分的后台管理系统都需要实现的功能,用户控制不同的角色能够进行的不同的操作。Spring Security的可以进行用户的角色权限控制,也可以进行用户的操作权限控制。在之前的代码实现上,我们仅仅只是实现用户的登录,在用户信息验证的时候使用UserDetailsService,但是却一直忽略了用户的权限。

一. 启动类配置

/**
 * 开启方法的注解安全校验。
 *  securedEnabled  @Secured("ROLE_abc")  该注解是Spring security提供的
 *  jsr250Enabled  @RolesAllowed("admin")  该注解是 JSR250 支持的注解形式
 *  prePostEnabled @PreAuthorize("hasAuthority(‘user:add‘)
 */
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class SecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class, args);
    }
}

二. 基于角色的权限控制

2.1 自定义认证信息类, 查询用户的密码和权限

@Component
public class UserSecurityService implements UserDetailsService {


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        /**
         * 调用形式有两种:
         *   1. 此时构建的 SimpleGrantedAuthority 必须是以 ROLE_ 开头, 例如 ROLE_admin, ROLE_manager.
         *      实现全权限控制的时候使用 @RolesAllowed("ROLE_admin")  或者 @RolesAllowed("admin") 都可以
         *   2. 此时构建的 SimpleGrantedAuthority 必须是以 ROLE_ 开头, 例如 ROLE_admin, ROLE_manager.
         *     实现全权限控制的时候使用 @Secured("ROLE_admin") ROLE_是不能省略的。
         */
        return new User(username, sysUser.getPassword(),
                Arrays.asList(new SimpleGrantedAuthority("ROLE_admin")));
    }
}

注意: 我们在构建SimpleGrantedAuthority对象的时候,用户的角色必须是以 ROLE_ 开头,例如 ROLE_adminROLE_manager

2.2 角色权限控制使用

在控制器上进行用户访问控制的时候,基于角色有两种书写方式:

方式一:@RolesAllowed

/**
 *  @RolesAllowed 中的值可以写成 "admin", 例如 @RolesAllowed("admin")
 *  推荐: @RolesAllowed 中的值还可以写成 "ROLE_admin",例如 @RolesAllowed("ROLE_admin")
 */
@RequestMapping
@RolesAllowed("admin")
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

方式二:@Secured

/**
 *  @Secured 中的值必须为 "ROLE_admin",例如 @Secured("ROLE_admin"),ROLE_不能省略
 */
@RequestMapping
@Secured("ROLE_admin")
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

三. 基于操作的权限控制

当然我们也可以使用基于操作的权限控制,这个功能稍显得有点累赘,因为在实际的项目开发过程中我们都是基于角色的权限控制。

3.1 自定义认证信息类, 查询用户的密码和权限

@Component
public class UserSecurityService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
         /**
         *  A. new SimpleGrantedAuthority("user:delete")   @PreAuthorize("hasAnyAuthority(‘user:add‘, ‘user:list‘)") 无法访问。
         *  B. new SimpleGrantedAuthority("user:add")     @PreAuthorize("hasAnyAuthority(‘user:add‘, ‘user:list‘)") 可以访问。
         *  C. Arrays.asList(new SimpleGrantedAuthority("user:add"), new SimpleGrantedAuthority("user:list"))
         *     @PreAuthorize("hasAuthority(‘user:add‘) and hasAuthority(‘user:list‘)") 可以访问
         *  D. new SimpleGrantedAuthority("ROLE_admin") 定义角色
         *    @PreAuthorize("hasRole(‘admin‘)")  可以访问
         */
        return new User(username, sysUser.getPassword(),
                Arrays.asList(new SimpleGrantedAuthority("user:list"),
                new SimpleGrantedAuthority("user:add")
                ));
    }
}

3.2 控制器访问控制(针对角色)

/**
 *  @PreAuthorize 中的值可以为 "ROLE_admin", "admin",
 *  例如 @PreAuthorize("hasRole(‘admin‘)") 或者为  
 *      @PreAuthorize("hasRole(‘ROLE_admin‘)")
 */
@RequestMapping
@PreAuthorize("hasRole(‘admin‘)")
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

3.3 控制器访问控制(针对操作)

@RequestMapping
// @PreAuthorize("hasAuthority(‘user:add‘) and hasAuthority(‘user:list‘)") 
// @PreAuthorize("hasAuthority(‘user:add‘) or hasAuthority(‘user:list‘)")
@PreAuthorize("hasAnyAuthority(‘user:add‘, ‘user:list‘)") 
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

3.4 访问无权限处理

.and()
.exceptionHandling()
.accessDeniedHandler(customizeAccessDeniedHandler)  //无权限访问处理, customizeAccessDeniedHandler为无权限处理操作类
.and()

四 .示例

4.1 用户权限表设计

 
技术图片
 

sql脚本

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `permmit` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
BEGIN;
INSERT INTO `sys_permission` VALUES (1, ‘删除用户‘, ‘user:delete‘);
INSERT INTO `sys_permission` VALUES (2, ‘展示用户‘, ‘user‘);
INSERT INTO `sys_permission` VALUES (3, ‘添加用户‘, ‘user:add‘);
INSERT INTO `sys_permission` VALUES (4, ‘编辑用户‘, ‘user:edit‘);
INSERT INTO `sys_permission` VALUES (5, ‘导出用户‘, ‘user:export‘);
INSERT INTO `sys_permission` VALUES (6, ‘部门展示‘, ‘dept‘);
INSERT INTO `sys_permission` VALUES (7, ‘删除部门‘, ‘dept:delete‘);
COMMIT;

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(20) NOT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_role
-- --

上一篇:java异常处理

下一篇:Spring


评论


亲,登录后才可以留言!