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 '' COMMENT '状态 1-正常,0-禁用,-1-删除',
- `create_time` int(11) unsigned NOT NULL COMMENT '添加时间',
- `last_login_time` int(11) unsigned DEFAULT '' COMMENT '上次登陆时间',
- `last_login_ip` varchar(40) DEFAULT NULL COMMENT '上次登录IP',
- `login_count` mediumint(8) unsigned DEFAULT '' COMMENT '登陆次数',
- PRIMARY KEY (`id`),
- UNIQUE KEY `account` (`account`)
- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='管理员';
- -- ----------------------------
- -- Records of user
- -- ----------------------------
- INSERT INTO `user` VALUES ('', 'super', 'ba98ee766e18d8352c9ad4add8387d54', 'z11qq118@126.com', '', '', '', '', '');
- INSERT INTO `user` VALUES ('', 'superadmin', 'e2dfe8256580c9d514863979f86b43b6', 'z11z13@126.com1', '', '', '', '127.0.0.1', '');
- INSERT INTO `user` VALUES ('', 'manager', '0da1810a78a0a6134d4535b995df8e89', '123@qq.com', '', '', '', '', '');
角色表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 ('', 'admin', '超级管理员');
- INSERT INTO `role` VALUES ('', '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 ('', '');
- INSERT INTO `user_role` VALUES ('', '');
权限表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 ('', '/user', 'user:user');
- INSERT INTO `permission` VALUES ('', '/user/add', 'user:add');
- INSERT INTO `permission` VALUES ('', '/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 ('', '');
- INSERT INTO `role_permission` VALUES ('', '');
- INSERT INTO `role_permission` VALUES ('', '');
- INSERT INTO `role_permission` VALUES ('', '');
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;
- }
- }
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> {
- }
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);
- }
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);
- }
- }
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>
(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();
- }
- }
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);
- }
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);
- }
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);
- }
- }
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>
(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();
- }
- }
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);
- }
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);
- }
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);
- }
- }
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 <> ''
- </select>
- </mapper>
(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;
- }
- }
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> {
- }
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>
(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;
- }
- }
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> {
- }
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>
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>
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>
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>
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
相关代码 地址
Spring boot后台搭建二集成Shiro权限控制的更多相关文章
- Spring boot后台搭建二集成Shiro实现用户验证
上一篇文章中介绍了Shiro 查看 将Shiro集成到spring boot的步骤: (1)定义一个ShiroConfig,配置SecurityManager Bean,SecurityManager ...
- Spring boot后台搭建二集成Shiro添加Remember Me
上一片文章实现了用户验证 查看 当用户成功登录后,关闭浏览器,重新打开浏览器访问http://localhost:8080,页面会跳转到登录页,因为浏览器的关闭后之前的登录已失效 Shiro提供了R ...
- Spring boot后台搭建二为Shiro权限控制添加缓存
在添加权限控制后,添加方法 查看 当用户访问”获取用户信息”.”新增用户”和”删除用户”的时,后台输出打印如下信息 , Druid数据源SQL监控 为了避免频繁访问数据库获取权限信息,在Shiro中加 ...
- 七、spring boot 1.5.4 集成shiro+cas,实现单点登录和权限控制
1.安装cas-server-3.5.2 官网:https://github.com/apereo/cas/releases/tag/v3.5.2 下载地址:cas-server-3.5.2-rele ...
- Spring boot后台搭建一使用MyBatis集成Mapper和PageHelper
目标: 使用 Spring boot+MyBatis+mysql 集成 Mapper 和 PageHelper,实现基本的增删改查 先建一个基本的 Spring Boot 项目开启 Spring B ...
- 2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(二)shiro权限注解 shiro注 ...
- Spring Boot 2.X(二):集成 MyBatis 数据层开发
MyBatis 简介 概述 MyBatis 是一款优秀的持久层框架,支持定制化 SQL.存储过程以及高级映射.它采用面向对象编程的方式对数据库进行 CRUD 的操作,使程序中对关系数据库的操作更方便简 ...
- Spring Boot(十四):spring boot整合shiro-登录认证和权限管理
Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...
- spring boot / cloud (十二) 异常统一处理进阶
spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...
随机推荐
- 动态生成16位不重复随机数、随机创建2位ID
/** 1. * 动态生成16位不重复随机数 * * @return */ public synchronized static String generate16() { StringBuffer ...
- Python练习题——用列表的方法输出杨辉三角
def main(): num = int(input('请输入行数: ')) yh = [[]] * num #创建num行空列表 for row in range(len(yh)): #遍历每一行 ...
- test20190903 JKlover
100+65+100=265,T2就差了一点. 乌合之众 给出一个 n × n 的, 元素为自然数的矩阵.这个矩阵有许许多多个子矩阵, 定义它的所有子矩阵形成的集合为 S . 对于一个矩阵 k , 定 ...
- LeetCode 1219. Path with Maximum Gold
原题链接在这里:https://leetcode.com/problems/path-with-maximum-gold/ 题目: In a gold mine grid of size m * n, ...
- HDU 6091 - Rikka with Match | 2017 Multi-University Training Contest 5
思路来自 某FXXL 不过复杂度咋算的.. /* HDU 6091 - Rikka with Match [ 树形DP ] | 2017 Multi-University Training Conte ...
- 如何把上传图片时候的文件对象转换为图片的url !
getObjectURL(file) { var url = null; if (window.createObjectURL != undefined) { url = window.createO ...
- Theano入门笔记1:Theano中的Graph Structure
译自:http://deeplearning.net/software/theano/extending/graphstructures.html#graphstructures 理解Theano计算 ...
- [译博文]CUDA是什么
翻译自:https://blogs.nvidia.com/blog/2012/09/10/what-is-cuda-2/ 你可能并没有意识到,GPU的应用有多广泛,它不但用于视频.游戏以及科学研究中, ...
- 55、Spark Streaming:updateStateByKey以及基于缓存的实时wordcount程序
一.updateStateByKey 1.概述 SparkStreaming 7*24 小时不间断的运行,有时需要管理一些状态,比如wordCount,每个batch的数据不是独立的而是需要累加的,这 ...
- nodejs之express生成项目[windows平台]
安装nvm,nvm下载地址 用于管理多个版本node,此处可省略! 安装nodejs,nodejs下载地址 淘宝镜像 安装cnpm命令,后面包可以使用cnpm命令安装,此处可省略,如果安装了 ...