zoukankan      html  css  js  c++  java
  • shiro授权

    授权本质分为两部分:1、添加权限Flag 2、定义权限Flag

    权限Flag:角色(Role)和权限(Permission)

    Shiro 支持三种定义(角色/权限)方式:

    编程式:通过写 if/else 授权代码块完成: 

    Subject subject = SecurityUtils.getSubject();
    if(subject.hasRole(“admin”)) {
        //有权限
    } else {
        //无权限
    }
    Subject subject = SecurityUtils.getSubject();
    if(subject.subject.checkPermission("user:find:*")) {
        //有权限
    } else {
        //无权限
    }

    注解式:通过在执行的 Java 方法上放置相应的注解完成:

    @RequiresRoles("admin")
    public void hello() {
        //有权限
    }
        @GetMapping("/add")
        @RequiresPermissions(value={"user:add:*"})
        public String add(){
            return "add";
        }

    没有权限将抛出相应的异常;

    JSP/GSP 标签:在 JSP/GSP 页面通过相应的标签完成:

    <shiro:hasRole name="admin">
    <!— 有权限 —>
    </shiro:hasRole>

    角色(Role)

    前期准备

    Role数据准备

    CREATE TABLE `t_role`  (
      `ROLE_ID` BIGINT(0) NOT NULL AUTO_INCREMENT COMMENT '角色ID',
      `ROLE_NAME` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '角色名称',
      `REMARK` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '角色描述',
      `DELETE_FLAG` TINYINT(0) NOT NULL DEFAULT 0 COMMENT '删除',
      `CREATE_TIME` DATETIME(0) NOT NULL COMMENT '创建时间',
      `CREATE_USER` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '创建人',
      `MODIFY_TIME` DATETIME(0) NOT NULL COMMENT '修改时间',
      `MODIFY_USER` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '修改人',
      PRIMARY KEY (`ROLE_ID`) USING BTREE,
      INDEX `t_role_index1`(`ROLE_ID`) USING BTREE
    ) ENGINE = INNODB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
    
    -- ----------------------------
    -- Records of t_role
    -- ----------------------------
    INSERT INTO `t_role` VALUES (1, '管理员', '管理员', 0, '2021-06-15 10:04:36', 'sys', '2021-06-23 13:14:31', 'admin');
    INSERT INTO `t_role` VALUES (2, '宾客', '宾客', 0, '2021-06-15 10:04:36', 'sys', '2021-06-23 13:14:40', 'admin');
    
    
    CREATE TABLE `t_user_role`  (
      `ID` BIGINT(0) NOT NULL AUTO_INCREMENT COMMENT '管理ID',
      `USER_ID` BIGINT(0) NOT NULL COMMENT '用户ID',
      `ROLE_ID` BIGINT(0) NOT NULL COMMENT '角色ID',
      `DELETE_FLAG` TINYINT(0) NOT NULL DEFAULT 0 COMMENT '删除',
      `CREATE_TIME` DATETIME(0) NOT NULL COMMENT '创建时间',
      `CREATE_USER` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '创建人',
      `MODIFY_TIME` DATETIME(0) NOT NULL COMMENT '修改时间',
      `MODIFY_USER` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '修改人',
      PRIMARY KEY (`ID`) USING BTREE,
      INDEX `t_user_index1`(`ID`, `USER_ID`, `ROLE_ID`) USING BTREE
    ) ENGINE = INNODB AUTO_INCREMENT = 147 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
    
    
    INSERT INTO `t_user_role`(`ID`, `USER_ID`, `ROLE_ID`, `DELETE_FLAG`, `CREATE_TIME`, `CREATE_USER`, `MODIFY_TIME`, `MODIFY_USER`) VALUES (1, 1, 1, 0, '2019-01-23 07:33:20', 'sys', '2020-11-27 16:12:21', '管理员');
    INSERT INTO `t_user_role`(`ID`, `USER_ID`, `ROLE_ID`, `DELETE_FLAG`, `CREATE_TIME`, `CREATE_USER`, `MODIFY_TIME`, `MODIFY_USER`) VALUES (2, 2, 2, 0, '2019-01-23 07:33:20', 'sys', '2020-11-27 16:12:21', '管理员');
    View Code

    RoleMapper

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.marw.mapper.RoleMapper">
        <resultMap id="roleMap" type="om.marw.entity.Role">
            <result column="ROLE_ID" jdbcType="DECIMAL" property="roleId"/>
            <result column="ROLE_NAME" jdbcType="VARCHAR" property="roleName"/>
            <result column="REMARK" jdbcType="VARCHAR" property="remark"/>
            <result column="CREATE_TIME" jdbcType="TIMESTAMP" property="createTime"/>
            <result column="MODIFY_TIME" jdbcType="TIMESTAMP" property="modifyTime"/>
        </resultMap>
    
        <select id="findUserRole" resultMap="roleMap">
            select r.*
            from t_role r
                     inner join t_user_role ur on (r.role_id = ur.role_id)
                     inner join t_user u on (u.user_id = ur.user_id)
            where u.username = #{userName}
              and r.DELETE_FLAG = '0'
              and ur.DELETE_FLAG = '0'
        </select>
    </mapper>
    View Code

    RoleServiceImpl

    @Service
    public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
        @Override
        public List<Role> findUserRole(String userName) {
            return baseMapper.findUserRole(userName);
        }
    }
    View Code

    添加角色

    认证和授权的操作都是在Realm中完成的

        @Autowired
        private IRoleService roleServiceImpl;
    
        /**
         * 授权
         * @param principalCollection
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("123");
            String username = (String) principalCollection.getPrimaryPrincipal();
    
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    
            // 获取用户角色集
            List<Role> roleList = roleServiceImpl.findUserRole(username);
            Set<String> roleSet = roleList.stream().map(Role::getRoleName).collect(Collectors.toSet());
            simpleAuthorizationInfo.setRoles(roleSet);
    
            return simpleAuthorizationInfo;
        }

    如果不定义角色,这个授权就没有任何意义

    定义角色

    用户角色为管理员可以用户管理、角色管理、菜单管理,用户角色是宾客只能访问用户管理

    shiro整合thymeleaf

    添加依赖

            <dependency>
                <groupId>com.github.theborakompanioni</groupId>
                <artifactId>thymeleaf-extras-shiro</artifactId>
                <version>2.0.0</version>
            </dependency>

    添加配置:在ShiroConfig配置类中定义整合thymeleaf

        //用于整合shiro、thymeleaf
        @Bean
        public ShiroDialect shiroDialect(){
            return new ShiroDialect();
        }

    前端页面:使用标签方式定义角色

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org"
          xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    首页<br />
    <div shiro:hasAnyRoles="管理员,宾客">
    <a href="/user/list">用户管理</a><br />
    </div>
    <div shiro:hasRole="管理员">
        <a href="/role/list">角色管理</a><br />
        <a href="/menu/list">菜单管理</a><br />
    </div>
    shiro:guest:判断是否是未登录,即游客<br />
    shiro:hasRole:判断是否有xxx角色<br />
    shiro:hasPermission:判断是否有xxx权限<br />
    shiro:hasAnyRoles:判断是否有任何一个指定的权限<br />
    </body>
    </html>
    View Code

    实际开发中,逻辑思想:用户具有什么角色,角色具有哪些权限,角色可以有菜单权限和操作权限

    权限(Permission)

    字符串通配符权限

    规则:“资源标识符:操作:对象实例 ID” 即对哪个资源的哪个实例可以进行什么操作。其默认支持通配符权限字符串,“:”表示资源/操作/实例的分割;“,”表示操作的分割;“*”表示任意资源/操作/实例。

    权限:菜单权限(显示菜单)和操作权限(增、删、改、查)

    角色和权限的关系:

    前期准备

    菜单、操作权限与角色关联的数据准备

    CREATE TABLE `t_menu` (
      `MENU_ID` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单/按钮ID',
      `PARENT_ID` bigint NOT NULL COMMENT '上级菜单ID',
      `MENU_NAME` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '菜单/按钮名称',
      `PATH` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '对应路由path',
      `COMPONENT` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '对应路由组件component',
      `PERMS` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '权限标识',
      `ICON` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '图标',
      `TYPE` char(2) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '类型 0菜单 1按钮',
      `ORDER_NUM` double(20,0) DEFAULT NULL COMMENT '排序',
      `DELETE_FLAG` tinyint NOT NULL DEFAULT '0' COMMENT '删除',
      `CREATE_TIME` datetime NOT NULL COMMENT '创建时间',
      `CREATE_USER` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '创建人',
      `MODIFY_TIME` datetime NOT NULL COMMENT '修改时间',
      `MODIFY_USER` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '修改人',
      PRIMARY KEY (`MENU_ID`) USING BTREE,
      KEY `t_menu_index1` (`MENU_ID`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=117 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=COMPACT;
    
    insert  into `t_menu`(`MENU_ID`,`PARENT_ID`,`MENU_NAME`,`PATH`,`COMPONENT`,`PERMS`,`ICON`,`TYPE`,`ORDER_NUM`,`DELETE_FLAG`,`CREATE_TIME`,`CREATE_USER`,`MODIFY_TIME`,`MODIFY_USER`) values 
    (1,0,'系统管理','/','PageView',NULL,'appstore-o','0',1,0,'2017-12-27 16:39:07','管理员','2021-06-15 11:40:23','admin'),
    (2,1,'用户管理','/user/list','User',NULL,'','0',1,0,'2017-12-27 16:47:13','管理员','2021-06-17 15:45:26','admin'),
    (3,1,'角色管理','/role/list','Role',NULL,'','0',2,1,'2017-12-27 16:48:09','管理员','2017-12-27 16:48:09','管理员'),
    (4,1,'菜单管理','/menu/list','Menu',NULL,'','0',3,1,'2017-12-27 16:48:57','管理员','2017-12-27 16:48:57','管理员'),
    (5,2,'新增用户','','','user:add',NULL,'1',NULL,0,'2017-12-27 17:02:58','管理员','2017-12-27 17:02:58','管理员'),
    (6,2,'修改用户','','','user:update',NULL,'1',NULL,0,'2017-12-27 17:04:07','管理员','2017-12-27 17:04:07','管理员'),
    (7,2,'删除用户','','','user:delete',NULL,'1',NULL,0,'2017-12-27 17:04:58','管理员','2017-12-27 17:04:58','管理员'),
    (8,3,'新增角色','','','role:add',NULL,'1',NULL,0,'2017-12-27 17:06:38','管理员','2017-12-27 17:06:38','管理员'),
    (9,3,'修改角色','','','role:update',NULL,'1',NULL,0,'2017-12-27 17:06:38','管理员','2017-12-27 17:06:38','管理员'),
    (10,3,'删除角色','','','role:delete',NULL,'1',NULL,0,'2017-12-27 17:06:38','管理员','2017-12-27 17:06:38','管理员'),
    (11,4,'新增菜单','','','menu:add',NULL,'1',NULL,0,'2017-12-27 17:08:02','管理员','2017-12-27 17:08:02','管理员'),
    (12,4,'修改菜单','','','menu:update',NULL,'1',NULL,0,'2017-12-27 17:08:02','管理员','2017-12-27 17:08:02','管理员'),
    (13,4,'删除菜单','','','menu:delete',NULL,'1',NULL,0,'2017-12-27 17:08:02','管理员','2017-12-27 17:08:02','管理员');
    
    
    CREATE TABLE `t_role_menu` (
      `ID` bigint NOT NULL AUTO_INCREMENT COMMENT '管理ID',
      `ROLE_ID` bigint NOT NULL COMMENT '角色ID',
      `MENU_ID` bigint NOT NULL COMMENT '菜单ID',
      `DELETE_FLAG` tinyint NOT NULL DEFAULT '0' COMMENT '删除',
      `CREATE_TIME` datetime NOT NULL COMMENT '创建时间',
      `CREATE_USER` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '创建人',
      `MODIFY_TIME` datetime NOT NULL COMMENT '修改时间',
      `MODIFY_USER` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '修改人',
      PRIMARY KEY (`ID`) USING BTREE,
      KEY `t_role_menu_index1` (`ID`,`ROLE_ID`,`MENU_ID`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=1946 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=COMPACT;
    
    /*Data for the table `t_role_menu` */
    
    insert  into `t_role_menu`(`ID`,`ROLE_ID`,`MENU_ID`,`DELETE_FLAG`,`CREATE_TIME`,`CREATE_USER`,`MODIFY_TIME`,`MODIFY_USER`) values 
    (1886,1,1,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1887,1,2,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1888,1,3,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1889,1,4,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1890,1,5,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1891,1,6,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1892,1,7,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1893,1,8,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1894,1,9,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1895,1,10,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1896,1,11,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1897,1,12,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1898,1,13,0,'2021-06-23 13:14:31','admin','2021-06-23 13:14:31','admin'),
    (1916,2,2,0,'2021-06-23 13:14:40','admin','2021-06-23 13:14:40','admin'),
    (1917,2,5,0,'2021-06-23 13:14:40','admin','2021-06-23 13:14:40','admin'),
    (1918,2,6,0,'2021-06-23 13:14:41','admin','2021-06-23 13:14:41','admin'),
    (1919,2,7,0,'2021-06-23 13:14:41','admin','2021-06-23 13:14:41','admin');
    View Code

    MenuMapper

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.marw.mapper.MenuMapper">
        <resultMap id="menu" type="com.marw.entity.Menu">
            <id column="MENU_ID" jdbcType="DECIMAL" property="menuId"/>
            <result column="PARENT_ID" jdbcType="DECIMAL" property="parentId"/>
            <result column="MENU_NAME" jdbcType="VARCHAR" property="menuName"/>
            <result column="PATH" jdbcType="VARCHAR" property="path"/>
            <result column="COMPONENT" jdbcType="VARCHAR" property="component"/>
            <result column="PERMS" jdbcType="VARCHAR" property="perms"/>
            <result column="ICON" jdbcType="VARCHAR" property="icon"/>
            <result column="TYPE" jdbcType="CHAR" property="type"/>
            <result column="ORDER_NUM" jdbcType="DOUBLE" property="orderNum"/>
            <result column="CREATE_TIME" jdbcType="TIMESTAMP" property="createTime"/>
            <result column="MODIFY_TIME" jdbcType="TIMESTAMP" property="modifyTime"/>
        </resultMap>
    
        <select id="findUserPermissions" resultMap="menu">
            select distinct m.perms
            from t_role r
                     left join t_user_role ur on (r.role_id = ur.role_id and ur.DELETE_FLAG = '0')
                     left join t_user u on (u.user_id = ur.user_id and u.STATUS = '1')
                     left join t_role_menu rm on (rm.role_id = r.role_id and rm.DELETE_FLAG = '0')
                     left join t_menu m on (m.menu_id = rm.menu_id and m.DELETE_FLAG = '0')
            where u.username = #{userName}
              and m.perms is not null
              and m.perms &lt;&gt; ''
              and m.DELETE_FLAG = '0'
        </select>
    </mapper>
    View Code

    MenuServiceImpl

    @Service
    public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
        @Override
        public List<Menu> findUserPermissions(String username) {
            return this.baseMapper.findUserPermissions(username);
        }
    }
    View Code

    添加权限

        @Autowired
        private IMenuService menuServiceImpl;
    
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String username = (String) principalCollection.getPrimaryPrincipal();
    
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    
            // 获取用户角色集
            List<Role> roleList = roleServiceImpl.findUserRole(username);
            Set<String> roleSet = roleList.stream().map(Role::getRoleName).collect(Collectors.toSet());
            simpleAuthorizationInfo.setRoles(roleSet);
    
            // 获取用户权限集
            List<Menu> permissionList = menuServiceImpl.findUserPermissions(username);
            Set<String> permissionSet = permissionList.stream().map(Menu::getPerms).collect(Collectors.toSet());
            simpleAuthorizationInfo.setStringPermissions(permissionSet);
            return simpleAuthorizationInfo;
        }

    定义权限

    管理员可以用户管理(增、删、改)、角色管理(增、删、改)、菜单管理(增、删、改),用户角色是宾客只能访问用户管理(增、删、改)

    用户管理

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @GetMapping("/list")
        public ModelAndView list(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("user/list");
            return modelAndView;
        }
    
        @GetMapping("/add")
        @RequiresPermissions(value={"user:add"})
        public ModelAndView add(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("user/add");
            return modelAndView;
        }
    
        @GetMapping("/update")
        @RequiresPermissions(value={"user:update"})
        public ModelAndView update(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("user/update");
            return modelAndView;
        }
    
        @GetMapping("/delete")
        @RequiresPermissions(value={"user:delete"})
        public ModelAndView delete(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("user/delete");
            return modelAndView;
        }
    }
    View Code

    角色管理

    @RestController
    @RequestMapping("/role")
    public class RoleController {
        @RequestMapping("/list")
        public ModelAndView list(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("role/list");
            return modelAndView;
        }
    
        @RequestMapping("/add")
        //@RequiresPermissions("role:add")
        public ModelAndView add(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("role/add");
            return modelAndView;
        }
    
        @RequestMapping("/update")
        @RequiresPermissions("role:update")
        public ModelAndView update(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("role/update");
            return modelAndView;
        }
    
        @RequestMapping("/delete")
        @RequiresPermissions("role:delete")
        public ModelAndView delete(){
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("role/delete");
            return modelAndView;
        }
    }
    View Code
  • 相关阅读:
    H-ui前端框架
    表单验证
    Switch 语句
    mysql下优化表和修复表命令使用说明(REPAIR TABLE和OPTIMIZE TABLE)
    mysql之repair table 修复表札记
    社会化海量数据采集爬虫框架搭建
    微信开发学习路线
    搜索引擎的商业价值
    centos7图形配置 firewall-config
    恢复gvim的ctl+v可视模式设置
  • 原文地址:https://www.cnblogs.com/WarBlog/p/15181687.html
Copyright © 2011-2022 走看看