• Spring boot后台搭建二集成Shiro权限控制


    上一篇文章,实现了用户验证 查看,接下来实现下权限控制

    权限控制,是管理资源访问的过程,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等

    Apache Shiro 通过继承AuthorizingRealm自定义实现ShiroRealm类,实现 doGetAuthenticationInfo()方法完成用户认证,实现doGetAuthorizationInfo()方法完成权限控制

    ShiroRealm 涉及到: 
      principal:主体,就是登陆的当前用户类型的数据实体 
      credentials:凭证,用户的密码,具体加密方式用户自己实现,什么都不做就是原文

    1.数据库

    shiro本身只提供拦截路由,具体的数据源则由用户自己提供

    使用RBAC(Role-Based Access Control,基于角色的访问控制)设计用户,角色和权限间的关系

    表结构

    用户表user

    CREATE TABLE `user` (
      `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
      `account` varchar(64) NOT NULL COMMENT '账号',
      `password` char(32) NOT NULL COMMENT '密码',
      `email` varchar(50) NOT NULL COMMENT '邮箱',
      `status` tinyint(1) DEFAULT '0' COMMENT '状态 1-正常,0-禁用,-1-删除',
      `create_time` int(11) unsigned NOT NULL COMMENT '添加时间',
      `last_login_time` int(11) unsigned DEFAULT '0' COMMENT '上次登陆时间',
      `last_login_ip` varchar(40) DEFAULT NULL COMMENT '上次登录IP',
      `login_count` mediumint(8) unsigned DEFAULT '0' COMMENT '登陆次数',
      PRIMARY KEY (`id`),
      UNIQUE KEY `account` (`account`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='管理员';
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES ('1', 'super', 'ba98ee766e18d8352c9ad4add8387d54', 'z11qq118@126.com', '1', '0', '1554273147', '2887450713', '223');
    INSERT INTO `user` VALUES ('2', 'superadmin', 'e2dfe8256580c9d514863979f86b43b6', 'z11z13@126.com1', '1', '1496993690', '1496993732', '127.0.0.1', '0');
    INSERT INTO `user` VALUES ('3', 'manager', '0da1810a78a0a6134d4535b995df8e89', '123@qq.com', '1', '1530083227', '1542873068', '2130706433', '9');

    角色表role

    CREATE TABLE `role` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(100) DEFAULT NULL COMMENT '角色名称',
      `memo` varchar(100) DEFAULT NULL COMMENT '角色描述',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of role
    -- ----------------------------
    INSERT INTO `role` VALUES ('1', 'admin', '超级管理员');
    INSERT INTO `role` VALUES ('2', 'test', '测试账户');

    用户角色关联表user_role

    CREATE TABLE `user_role` (
      `uid` int(10) DEFAULT NULL COMMENT '用户id',
      `rid` int(10) DEFAULT NULL COMMENT '角色id'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of user_role
    -- ----------------------------
    INSERT INTO `user_role` VALUES ('1', '1');
    INSERT INTO `user_role` VALUES ('3', '2');

    权限表permission

    CREATE TABLE `permission` (
      `id` int(10) NOT NULL,
      `url` varchar(255) DEFAULT NULL COMMENT 'url地址',
      `name` varchar(100) DEFAULT NULL COMMENT 'url描述',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of permission
    -- ----------------------------
    INSERT INTO `permission` VALUES ('1', '/user', 'user:user');
    INSERT INTO `permission` VALUES ('2', '/user/add', 'user:add');
    INSERT INTO `permission` VALUES ('3', '/user/delete', 'user:delete');

    权限角色关联表role_permission

    CREATE TABLE `role_permission` (
      `rid` int(10) DEFAULT NULL COMMENT '角色id',
      `pid` int(10) DEFAULT NULL COMMENT '权限id'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of role_permission
    -- ----------------------------
    INSERT INTO `role_permission` VALUES ('1', '2');
    INSERT INTO `role_permission` VALUES ('1', '3');
    INSERT INTO `role_permission` VALUES ('2', '1');
    INSERT INTO `role_permission` VALUES ('1', '1');

    2.数据层

    修改mybatis-generator.xml中的tableName和domainObjectName,自动生成上面上面表的相关代码再进行添加或修改

    <table tableName="USER" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
         <generatedKey column="id" sqlStatement="mysql" identity="true"/>
    </table>

      (1)User

        User

    package com.sfn.bms.system.model;
    
    import java.io.Serializable;
    import javax.persistence.*;
    
    public class User implements Serializable {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Short id;
    
        /**
         * 账号
         */
        private String account;
    
        /**
         * 密码
         */
        private String password;
    
        /**
         * 邮箱
         */
        private String email;
    
        /**
         * 状态 1-正常,0-禁用,-1-删除
         */
        private Boolean status;
    
        /**
         * 添加时间
         */
        @Column(name = "create_time")
        private Integer createTime;
    
        /**
         * 上次登陆时间
         */
        @Column(name = "last_login_time")
        private Integer lastLoginTime;
    
        /**
         * 上次登录IP
         */
        @Column(name = "last_login_ip")
        private String lastLoginIp;
    
        /**
         * 登陆次数
         */
        @Column(name = "login_count")
        private Integer loginCount;
    
        private static final long serialVersionUID = 1L;
    
        /**
         * @return id
         */
        public Short getId() {
            return id;
        }
    
        /**
         * @param id
         */
        public void setId(Short id) {
            this.id = id;
        }
    
        /**
         * 获取账号
         *
         * @return account - 账号
         */
        public String getAccount() {
            return account;
        }
    
        /**
         * 设置账号
         *
         * @param account 账号
         */
        public void setAccount(String account) {
            this.account = account == null ? null : account.trim();
        }
    
        /**
         * 获取密码
         *
         * @return password - 密码
         */
        public String getPassword() {
            return password;
        }
    
        /**
         * 设置密码
         *
         * @param password 密码
         */
        public void setPassword(String password) {
            this.password = password == null ? null : password.trim();
        }
    
        /**
         * 获取邮箱
         *
         * @return email - 邮箱
         */
        public String getEmail() {
            return email;
        }
    
        /**
         * 设置邮箱
         *
         * @param email 邮箱
         */
        public void setEmail(String email) {
            this.email = email == null ? null : email.trim();
        }
    
        /**
         * 获取状态 1-正常,0-禁用,-1-删除
         *
         * @return status - 状态 1-正常,0-禁用,-1-删除
         */
        public Boolean getStatus() {
            return status;
        }
    
        /**
         * 设置状态 1-正常,0-禁用,-1-删除
         *
         * @param status 状态 1-正常,0-禁用,-1-删除
         */
        public void setStatus(Boolean status) {
            this.status = status;
        }
    
        /**
         * 获取添加时间
         *
         * @return create_time - 添加时间
         */
        public Integer getCreateTime() {
            return createTime;
        }
    
        /**
         * 设置添加时间
         *
         * @param createTime 添加时间
         */
        public void setCreateTime(Integer createTime) {
            this.createTime = createTime;
        }
    
        /**
         * 获取上次登陆时间
         *
         * @return last_login_time - 上次登陆时间
         */
        public Integer getLastLoginTime() {
            return lastLoginTime;
        }
    
        /**
         * 设置上次登陆时间
         *
         * @param lastLoginTime 上次登陆时间
         */
        public void setLastLoginTime(Integer lastLoginTime) {
            this.lastLoginTime = lastLoginTime;
        }
    
        /**
         * 获取上次登录IP
         *
         * @return last_login_ip - 上次登录IP
         */
        public String getLastLoginIp() {
            return lastLoginIp;
        }
    
        /**
         * 设置上次登录IP
         *
         * @param lastLoginIp 上次登录IP
         */
        public void setLastLoginIp(String lastLoginIp) {
            this.lastLoginIp = lastLoginIp == null ? null : lastLoginIp.trim();
        }
    
        /**
         * 获取登陆次数
         *
         * @return login_count - 登陆次数
         */
        public Integer getLoginCount() {
            return loginCount;
        }
    
        /**
         * 设置登陆次数
         *
         * @param loginCount 登陆次数
         */
        public void setLoginCount(Integer loginCount) {
            this.loginCount = loginCount;
        }
    }
    View Code

        UserMapper

    package com.sfn.bms.system.mapper;
    
    import com.sfn.bms.common.config.MyMapper;
    import com.sfn.bms.system.model.User;
    
    public interface UserMapper extends MyMapper<User> {
    }
    View Code

        UserService(新增)

    package com.sfn.bms.system.service;
    
    import com.sfn.bms.common.service.IService;
    import com.sfn.bms.system.model.User;
    
    public interface UserService extends IService<User> {
        User findByAccount(String account);
    }
    View Code

        UserServiceImpl (新增)

    package com.sfn.bms.system.service.impl;
    
    import com.sfn.bms.common.service.impl.BaseService;
    import com.sfn.bms.system.model.User;
    import com.sfn.bms.system.service.UserService;
    import org.springframework.stereotype.Repository;
    import tk.mybatis.mapper.entity.Example;
    
    import java.util.List;
    
    @Repository("userService")
    public class UserServiceImpl extends BaseService<User> implements UserService {
        @Override
        public User findByAccount(String account) {
            Example example = new Example(User.class);
            example.createCriteria().andCondition("lower(account)=", account.toLowerCase());
            List<User> list = this.selectByExample(example);
            return list.isEmpty() ? null : list.get(0);
        }
    
    }
    View Code

        UserMapper.xml

    <?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.sfn.bms.system.mapper.UserMapper">
      <resultMap id="BaseResultMap" type="com.sfn.bms.system.model.User">
        <!--
          WARNING - @mbg.generated
        -->
        <id column="id" jdbcType="SMALLINT" property="id" />
        <result column="account" jdbcType="VARCHAR" property="account" />
        <result column="password" jdbcType="CHAR" property="password" />
        <result column="email" jdbcType="VARCHAR" property="email" />
        <result column="status" jdbcType="BIT" property="status" />
        <result column="create_time" jdbcType="INTEGER" property="createTime" />
        <result column="last_login_time" jdbcType="INTEGER" property="lastLoginTime" />
        <result column="last_login_ip" jdbcType="VARCHAR" property="lastLoginIp" />
        <result column="login_count" jdbcType="INTEGER" property="loginCount" />
      </resultMap>
    
    </mapper>
    View Code

      (2)Role

        Role 

    package com.sfn.bms.system.model;
    
    import java.io.Serializable;
    import javax.persistence.*;
    
    public class Role implements Serializable {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
    
        /**
         * 角色名称
         */
        private String name;
    
        /**
         * 角色描述
         */
        private String memo;
    
        private static final long serialVersionUID = 1L;
    
        /**
         * @return id
         */
        public Integer getId() {
            return id;
        }
    
        /**
         * @param id
         */
        public void setId(Integer id) {
            this.id = id;
        }
    
        /**
         * 获取角色名称
         *
         * @return name - 角色名称
         */
        public String getName() {
            return name;
        }
    
        /**
         * 设置角色名称
         *
         * @param name 角色名称
         */
        public void setName(String name) {
            this.name = name == null ? null : name.trim();
        }
    
        /**
         * 获取角色描述
         *
         * @return memo - 角色描述
         */
        public String getMemo() {
            return memo;
        }
    
        /**
         * 设置角色描述
         *
         * @param memo 角色描述
         */
        public void setMemo(String memo) {
            this.memo = memo == null ? null : memo.trim();
        }
    }
    View Code

        RoleMapper(修改)

    package com.sfn.bms.system.mapper;
    
    import com.sfn.bms.common.config.MyMapper;
    import com.sfn.bms.system.model.Role;
    
    import java.util.List;
    
    public interface RoleMapper extends MyMapper<Role> {
        List<Role> findUserRole(String account);
    }
    View Code

        RoleService (新增)

    package com.sfn.bms.system.service;
    
    import com.sfn.bms.common.service.IService;
    import com.sfn.bms.system.model.Role;
    
    import java.util.List;
    
    public interface RoleService extends IService<Role> {
        List<Role> findUserRole(String account);
    }
    View Code

        RoleServiceImpl (新增)

    package com.sfn.bms.system.service.impl;
    
    import com.sfn.bms.common.service.impl.BaseService;
    import com.sfn.bms.system.mapper.RoleMapper;
    import com.sfn.bms.system.model.Role;
    import com.sfn.bms.system.service.RoleService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.List;
    
    @Service("RoleService")
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
    public class RoleServiceImpl extends BaseService<Role> implements RoleService {
    
        @Autowired
        private RoleMapper mapper;
    
        @Override
        public List<Role> findUserRole(String account) {
            return this.mapper.findUserRole(account);
        }
    }
    View Code

        RoleMapper.xml(修改)

    <?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.sfn.bms.system.mapper.RoleMapper">
      <resultMap id="BaseResultMap" type="com.sfn.bms.system.model.Role">
        <!--
          WARNING - @mbg.generated
        -->
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="memo" jdbcType="VARCHAR" property="memo" />
      </resultMap>
      <select id="findUserRole" resultMap="BaseResultMap">
        select r.* from role r
        left join user_role ur on(r.id = ur.rid)
        left join user u on(u.id = ur.uid)
        where u.account = #{account}
      </select>
    </mapper>
    View Code

      (3)Permission    

        Permission 

    package com.sfn.bms.system.model;
    
    import java.io.Serializable;
    import javax.persistence.*;
    
    public class Permission implements Serializable {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
    
        /**
         * url地址
         */
        private String url;
    
        /**
         * url描述
         */
        private String name;
    
        private static final long serialVersionUID = 1L;
    
        /**
         * @return id
         */
        public Integer getId() {
            return id;
        }
    
        /**
         * @param id
         */
        public void setId(Integer id) {
            this.id = id;
        }
    
        /**
         * 获取url地址
         *
         * @return url - url地址
         */
        public String getUrl() {
            return url;
        }
    
        /**
         * 设置url地址
         *
         * @param url url地址
         */
        public void setUrl(String url) {
            this.url = url == null ? null : url.trim();
        }
    
        /**
         * 获取url描述
         *
         * @return name - url描述
         */
        public String getName() {
            return name;
        }
    
        /**
         * 设置url描述
         *
         * @param name url描述
         */
        public void setName(String name) {
            this.name = name == null ? null : name.trim();
        }
    }
    View Code

        PermissionMapper(修改)

    package com.sfn.bms.system.mapper;
    
    import com.sfn.bms.common.config.MyMapper;
    import com.sfn.bms.system.model.Permission;
    
    import java.util.List;
    
    public interface PermissionMapper extends MyMapper<Permission> {
        List<Permission> findUserPermissions(String account);
    }
    View Code

        PermissionService (新增)

    package com.sfn.bms.system.service;
    
    import com.sfn.bms.common.service.IService;
    import com.sfn.bms.system.model.Permission;
    
    import java.util.List;
    
    public interface  PermissionService extends IService<Permission> {
        List<Permission> findUserPermissions(String account);
    }
    View Code

        PermissionServiceImpl (新增)

    package com.sfn.bms.system.service.impl;
    
    import com.sfn.bms.common.service.impl.BaseService;
    import com.sfn.bms.system.mapper.PermissionMapper;
    import com.sfn.bms.system.model.Permission;
    import com.sfn.bms.system.service.PermissionService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.List;
    
    @Service("PermissionService")
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
    public class PermissionServiceImpl extends BaseService<Permission> implements PermissionService {
        @Autowired
        private PermissionMapper mapper;
        @Override
        public List<Permission> findUserPermissions(String account) {
            return this.mapper.findUserPermissions(account);
        }
    }
    View Code

        PermissionMapper.xml(修改)

    <?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.sfn.bms.system.mapper.PermissionMapper">
      <resultMap id="BaseResultMap" type="com.sfn.bms.system.model.Permission">
        <!--
          WARNING - @mbg.generated
        -->
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="url" jdbcType="VARCHAR" property="url" />
        <result column="name" jdbcType="VARCHAR" property="name" />
      </resultMap>
      <select id="findUserPermissions" resultMap="BaseResultMap">
        select p.* from role r
        left join user_role ur on(r.id = ur.rid)
        left join user u on(u.id = ur.uid)
        left join role_permission rp on(rp.rid = r.id)
        left join permission p on(p.id = rp.pid )
        where u.account = #{account} and p.name is not null and p.name &lt;&gt; ''
      </select>
    </mapper>
    View Code

      (4)UserRole

        UserRole 

    package com.sfn.bms.system.model;
    
    import java.io.Serializable;
    import javax.persistence.*;
    
    @Table(name = "user_role")
    public class UserRole implements Serializable {
        /**
         * 用户id
         */
        private Integer uid;
    
        /**
         * 角色id
         */
        private Integer rid;
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 获取用户id
         *
         * @return uid - 用户id
         */
        public Integer getUid() {
            return uid;
        }
    
        /**
         * 设置用户id
         *
         * @param uid 用户id
         */
        public void setUid(Integer uid) {
            this.uid = uid;
        }
    
        /**
         * 获取角色id
         *
         * @return rid - 角色id
         */
        public Integer getRid() {
            return rid;
        }
    
        /**
         * 设置角色id
         *
         * @param rid 角色id
         */
        public void setRid(Integer rid) {
            this.rid = rid;
        }
    }
    View Code

        UserRoleMapper

    package com.sfn.bms.system.mapper;
    
    import com.sfn.bms.common.config.MyMapper;
    import com.sfn.bms.system.model.UserRole;
    
    public interface UserRoleMapper extends MyMapper<UserRole> {
    }
    View Code

        UserRoleMapper.xml

    <?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.sfn.bms.system.mapper.UserRoleMapper">
      <resultMap id="BaseResultMap" type="com.sfn.bms.system.model.UserRole">
        <!--
          WARNING - @mbg.generated
        -->
        <result column="uid" jdbcType="INTEGER" property="uid" />
        <result column="rid" jdbcType="INTEGER" property="rid" />
      </resultMap>
    </mapper>
    View Code

      (5)RolePermission  

        RolePermission 

    package com.sfn.bms.system.model;
    
    import java.io.Serializable;
    import javax.persistence.*;
    
    @Table(name = "role_permission")
    public class RolePermission implements Serializable {
        /**
         * 角色id
         */
        private Integer rid;
    
        /**
         * 权限id
         */
        private Integer pid;
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 获取角色id
         *
         * @return rid - 角色id
         */
        public Integer getRid() {
            return rid;
        }
    
        /**
         * 设置角色id
         *
         * @param rid 角色id
         */
        public void setRid(Integer rid) {
            this.rid = rid;
        }
    
        /**
         * 获取权限id
         *
         * @return pid - 权限id
         */
        public Integer getPid() {
            return pid;
        }
    
        /**
         * 设置权限id
         *
         * @param pid 权限id
         */
        public void setPid(Integer pid) {
            this.pid = pid;
        }
    }
    View Code

      RolePermissionMapper

    package com.sfn.bms.system.mapper;
    
    import com.sfn.bms.common.config.MyMapper;
    import com.sfn.bms.system.model.RolePermission;
    
    public interface RolePermissionMapper extends MyMapper<RolePermission> {
    }
    View Code

      RolePermissionMapper.xml

    <?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.sfn.bms.system.mapper.RolePermissionMapper">
      <resultMap id="BaseResultMap" type="com.sfn.bms.system.model.RolePermission">
        <!--
          WARNING - @mbg.generated
        -->
        <result column="rid" jdbcType="INTEGER" property="rid" />
        <result column="pid" jdbcType="INTEGER" property="pid" />
      </resultMap>
    </mapper>
    View Code

    3.配置shiro相关文件

      (1)Realm

    package com.sfn.bms.common.shiro;
    import com.sfn.bms.system.model.Permission;
    import com.sfn.bms.system.model.Role;
    import com.sfn.bms.system.model.User;
    import com.sfn.bms.system.service.PermissionService;
    import com.sfn.bms.system.service.RoleService;
    import com.sfn.bms.system.service.UserService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.subject.SimplePrincipalCollection;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.stream.Collectors;
    
    /**
     * 自定义实现 ShiroRealm,包含认证和授权两大模块
     */
    @Component("shiroRealm")
    public class MyShiroRealm extends AuthorizingRealm {
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private RoleService roleService;
        @Autowired
        private PermissionService permissionService;
    
        /**
         * 授权模块,获取用户角色和权限
         *
         * @param principal principal
         * @return AuthorizationInfo 权限信息
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
    
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            String account = user.getAccount();
    
            System.out.println("用户" + account + "获取权限-----ShiroRealm.doGetAuthorizationInfo");
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    
            // 获取用户角色集
            List<Role> roleList = this.roleService.findUserRole(account);
            Set<String> roleSet = roleList.stream().map(Role::getName).collect(Collectors.toSet());
            simpleAuthorizationInfo.setRoles(roleSet);
    
            // 获取用户权限集
            List<Permission> permissionList = permissionService.findUserPermissions(account);
            Set<String> permissionSet = permissionList.stream().map(Permission::getName).collect(Collectors.toSet());
            simpleAuthorizationInfo.setStringPermissions(permissionSet);
    
            return simpleAuthorizationInfo;
        }
    
        /**
         * 用户认证
         *
         * @param token AuthenticationToken 身份认证 token
         * @return AuthenticationInfo 身份认证信息
         * @throws AuthenticationException 认证相关异常
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
           ……
        }
    }

      (2)ShiroConfig

        添加

    @Bean
        public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
            DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
            advisorAutoProxyCreator.setProxyTargetClass(true);
            return advisorAutoProxyCreator;
        }
    
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }

    4.使用

      (1)Controller

      添加UserController

    package com.sfn.bms.system.controller;
    
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import com.sfn.bms.system.model.Permission;
    import com.sfn.bms.system.model.Role;
    import com.sfn.bms.system.model.User;
    import com.sfn.bms.system.service.PermissionService;
    import com.sfn.bms.system.service.RoleService;
    import com.sfn.bms.system.service.UserService;
    import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.List;
    
    @Controller
    public class UserController {
    
        @Autowired
        UserService userService;
    
        @Autowired
        private RoleService roleService;
    
        @Autowired
        private PermissionService permissionService;
    
        @RequiresPermissions("user:user")
        @RequestMapping("user/list")
        public String userList(Model model) {
            model.addAttribute("value", "获取用户信息");
            return "user";
        }
    
        @RequiresPermissions("user:add")
        @RequestMapping("user/add")
        public String userAdd(Model model) {
            model.addAttribute("value", "新增用户");
            return "user";
        }
    
        @RequiresPermissions("user:delete")
        @RequestMapping("user/delete")
        public String userDelete(Model model) {
            model.addAttribute("value", "删除用户");
            return "user";
        }
    
    }

      在LoginController添加/403跳转

    @GetMapping("/403")
        public String forbid() {
            return "403";
    }

      (2)前端页面

      index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
        <p>你好![[${user.account}]]</p>
        <h3>用户管理</h3>
        <div>
            <a th:href="@{/user/list}">获取用户信息</a>
            <a th:href="@{/user/add}">新增用户</a>
            <a th:href="@{/user/delete}">删除用户</a>
        </div>
        <a th:href="@{/logout}">注销</a>
    </body>
    </html>
    View Code

      user.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>[[${value}]]</title>
    </head>
    <body>
        <p>[[${value}]]</p>
        <a th:href="@{/index}">返回</a>
    </body>
    </html>
    View Code

      error/403.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>暂无权限</title>
    </head>
    <body>
    <p>您没有权限访问该资源!!</p>
    <a th:href="@{/index}">返回</a>
    </body>
    </html>
    View Code

    5.测试

     启动项目,在登录页输入用户名 manager密码123456,来到主页

    数据库中manager属于test角色,没有添加和删除的权限,在跳转到新增用户或删除用户时,页面会被重定向到/403

    后台抛出异常org.apache.shiro.authz.AuthorizationException: Not authorized to invoke method

    定义一个全局异常捕获类

    package com.sfn.bms.common.handler;
    
    import com.sfn.bms.common.domian.ResponseBo;
    import com.sfn.bms.common.util.HttpUtils;
    import org.apache.shiro.authz.AuthorizationException;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    @RestControllerAdvice
    @Order(value = Ordered.HIGHEST_PRECEDENCE)
    public class GlobalExceptionHandler {
        @ExceptionHandler(value = AuthorizationException.class)
        public Object handleAuthorizationException(HttpServletRequest request) {
            if (HttpUtils.isAjaxRequest(request)) {
                return ResponseBo.error("暂无权限,请联系管理员!");
            } else {
                ModelAndView mav = new ModelAndView();
                mav.setViewName("error/403");
                return mav;
            }
        }
    }

    再次运行项目,登录后选择新增用户,页面成功重定向到/403

     

     相关代码 地址

  • 相关阅读:
    装饰器wraps
    装饰器的语法糖
    VisionPro 自学帮助
    准备重新编译VisionPro 官方版本 使用 vs2019
    个人随笔_学习感悟
    VisionPro 一些图操作
    System.Data.Sqlite.dll 使用异常问题参考
    NOPI笔记01
    VisionPro帮助文档学习01(UserGuide DisPlay)
    MSSqlServer基础学习01
  • 原文地址:https://www.cnblogs.com/baby123/p/11080223.html
Copyright © 2020-2023  润新知