授权
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 TransferSource Server : 本机Source Server Type : MySQLSource Server Version : 80029Source Host : localhost:3306Source Schema : shirodbTarget Server Type : MySQLTarget Server Version : 80029File Encoding : 65001Date: 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 TransferSource Server : 本机Source Server Type : MySQLSource Server Version : 80029Source Host : localhost:3306Source Schema : shirodbTarget Server Type : MySQLTarget Server Version : 80029File Encoding : 65001Date: 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 TransferSource Server : 本机Source Server Type : MySQLSource Server Version : 80029Source Host : localhost:3306Source Schema : shirodbTarget Server Type : MySQLTarget Server Version : 80029File Encoding : 65001Date: 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 TransferSource Server : 本机Source Server Type : MySQLSource Server Version : 80029Source Host : localhost:3306Source Schema : shirodbTarget Server Type : MySQLTarget Server Version : 80029File Encoding : 65001Date: 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层
@Overridepublic 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 | 验证当前用户是否拥有以下任意一个权限 |