授权
1、角色认证
在controller层创建接口
使用shiro中的注解@RequiresRoles指定能访问的角色名称
/**
* 登录认证角色
*/
@RequiresRoles("admin")
@GetMapping("/userLoginRoles")
@ResponseBody
public String userLoginRoles(){
System.out.println("登录认证验证角色");
return "管理员角色验证成功";
}
在自定义的MyRealm自定义授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//1、查询当前用户的身份信息
String principal = principalCollection.getPrimaryPrincipal().toString();
List<String> roles = userService.getUserRoleInfo(principal);
//2、创建对象,封装当前登录用户的角色、权限信息
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//3、存储角色
info.addRoles(roles);
System.out.println(roles);
return info;
}
其中的service层
@Override
public List<String> getUserRoleInfo(String principal) {
return userMapper.getUserRoleInfoMapper(principal);
}
dao层
@Select("select name from role where id in( select id from role_user where uid=(select id from user where name=#{principal}))")
List<String> getUserRoleInfoMapper(@Param("principal")String principal);
数据库表
role角色表
/*
Navicat Premium Data Transfer
Source Server : 本机
Source Server Type : MySQL
Source Server Version : 80029
Source Host : localhost:3306
Source Schema : shirodb
Target Server Type : MySQL
Target Server Version : 80029
File Encoding : 65001
Date: 22/12/2022 10:37:15
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` bigint NOT NULL COMMENT '编号',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色名',
`desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
`realname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色显示名',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, 'admin', '所有权限', '管理员');
INSERT INTO `role` VALUES (2, 'userMag', '用户管理权限', '用户管理');
SET FOREIGN_KEY_CHECKS = 1;
角色用户关系表
/*
Navicat Premium Data Transfer
Source Server : 本机
Source Server Type : MySQL
Source Server Version : 80029
Source Host : localhost:3306
Source Schema : shirodb
Target Server Type : MySQL
Target Server Version : 80029
File Encoding : 65001
Date: 22/12/2022 10:37:27
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role_user
-- ----------------------------
DROP TABLE IF EXISTS `role_user`;
CREATE TABLE `role_user` (
`id` int NOT NULL AUTO_INCREMENT,
`uid` int NULL DEFAULT NULL,
`rid` int NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of role_user
-- ----------------------------
INSERT INTO `role_user` VALUES (1, 1, 1);
INSERT INTO `role_user` VALUES (2, 1, 2);
INSERT INTO `role_user` VALUES (3, 2, 2);
SET FOREIGN_KEY_CHECKS = 1;
2、权限认证
创建权限表(permission)
sql语句
/*
Navicat Premium Data Transfer
Source Server : 本机
Source Server Type : MySQL
Source Server Version : 80029
Source Host : localhost:3306
Source Schema : shirodb
Target Server Type : MySQL
Target Server Version : 80029
File Encoding : 65001
Date: 22/12/2022 11:09:55
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for permission
-- ----------------------------
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`info` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of permission
-- ----------------------------
INSERT INTO `permission` VALUES (1, '删除用户', 'user:delete', '删除用户');
INSERT INTO `permission` VALUES (2, '新增用户', 'user:add', '新增用户');
INSERT INTO `permission` VALUES (3, '修改用户', 'user:endit', '修改用户');
SET FOREIGN_KEY_CHECKS = 1;
创建角色权限表
/*
Navicat Premium Data Transfer
Source Server : 本机
Source Server Type : MySQL
Source Server Version : 80029
Source Host : localhost:3306
Source Schema : shirodb
Target Server Type : MySQL
Target Server Version : 80029
File Encoding : 65001
Date: 22/12/2022 11:10:09
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role_ps
-- ----------------------------
DROP TABLE IF EXISTS `role_ps`;
CREATE TABLE `role_ps` (
`id` int NOT NULL,
`rid` int NULL DEFAULT NULL,
`pid` int NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of role_ps
-- ----------------------------
INSERT INTO `role_ps` VALUES (1, 1, 1);
INSERT INTO `role_ps` VALUES (2, 1, 2);
INSERT INTO `role_ps` VALUES (3, 1, 3);
SET FOREIGN_KEY_CHECKS = 1;
编写dao层
根据传来的角色名称查询对应的权限
@Select({"<script>"," SELECT info FROM permission where id in (select pid from role_ps where rid in (select id from role where name in <foreach collection='roles' item='name' open='(' separator=',' close=')' >#{name}</foreach> ))",
"</script>"
})
List<String> getUserPermissionInfo(@Param("roles") List<String> roles);
编写service层
@Override
public List<String> getUserPermissionInfo(List<String> roles) {
return userMapper.getUserPermissionInfo(roles);
}
在自定义realm中
自定义授权方法中,添加授权信息,在步骤2.5
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//1、查询当前用户的身份信息
String principal = principalCollection.getPrimaryPrincipal().toString();
List<String> roles = userService.getUserRoleInfo(principal);
//2、创建对象,封装当前登录用户的角色、权限信息
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//2.5获取用户的权限信息
List<String> permissions = userService.getUserPermissionInfo(roles);
//3、存储角色
info.addRoles(roles);
info.addStringPermissions(permissions);
System.out.println(roles);
return info;
}
编写测试接口,通过@RequiresPermissions(“user:delete”)指定授权信息
/**
* 登录认证权限
*/
@RequiresPermissions("user:delete")
@GetMapping("userPermissions")
@ResponseBody
public String userPermissions(){
System.out.println("登录认证验证权限");
return "user:delete权限验证成功";
}
前端页面
<a href="/myController/userPermissions">验证权限</a>
3、配置异常捕获
当用户访问无对应的权限,会直接抛出对应的异常,我们需要定义全局的异常捕获
例如:
@ControllerAdvice
public class PermisiionException {
@ResponseBody
@ExceptionHandler(UnauthorizedException.class)
public String unauthorizedException(Exception e){
return "无权限";
}
@ResponseBody
@ExceptionHandler(AuthorizationException.class)
public String unAuthorization(Exception e){
return "权限认证失败";
}
}
4、前端页面授权验证
在页面中所见即所得,当有哪些权限就展示对应的权限
这里使用thymeleaf来渲染前端页面
1、引入依赖
<!-- 配置Thymeleaf与Shiro的整合依赖-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2、在ShiroConfig中配置
@Bean(name = "shiroDialect")
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
3、添加坐标
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="Thymeleaf"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
4、测试
<a shiro:hasRole="admin" href="">管理员</a>
<a shiro:hasPermission="user:delete" href="">user:delete权限</a>
标签说明:
shiro:guest | 验证当前用户是否为“访客”,即未认证(包含未记住)的用户 |
shiro:user | 认证通过或已记住的用户 |
shiro:authenticated | 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在 |
shiro:notAuthenticated | 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户 |
shiro:hasRole | 验证当前用户是否属于该角色 |
shiro:lacksRole | 与hasRole标签逻辑相反,当用户不属于该角色时验证通过 |
shiro:hasAllRoles | 验证当前用户是否属于以下所有角色 |
shiro:hasAnyRoles | 验证当前用户是否属于以下任意一个角色 |
shiro:hasPermission | 验证当前用户是否拥有指定权限 |
shiro:lacksPermission | hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过 |
shiro:hasAllPermissions | 验证当前用户是否拥有以下所有权限 |
shiro:hasAnyPermissions | 验证当前用户是否拥有以下任意一个权限 |