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

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

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 &lt;&gt; ''
</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权限控制的更多相关文章

  1. Spring boot后台搭建二集成Shiro实现用户验证

    上一篇文章中介绍了Shiro 查看 将Shiro集成到spring boot的步骤: (1)定义一个ShiroConfig,配置SecurityManager Bean,SecurityManager ...

  2. Spring boot后台搭建二集成Shiro添加Remember Me

    上一片文章实现了用户验证  查看 当用户成功登录后,关闭浏览器,重新打开浏览器访问http://localhost:8080,页面会跳转到登录页,因为浏览器的关闭后之前的登录已失效 Shiro提供了R ...

  3. Spring boot后台搭建二为Shiro权限控制添加缓存

    在添加权限控制后,添加方法 查看 当用户访问”获取用户信息”.”新增用户”和”删除用户”的时,后台输出打印如下信息 , Druid数据源SQL监控 为了避免频繁访问数据库获取权限信息,在Shiro中加 ...

  4. 七、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 ...

  5. Spring boot后台搭建一使用MyBatis集成Mapper和PageHelper

    目标: 使用 Spring  boot+MyBatis+mysql 集成 Mapper 和 PageHelper,实现基本的增删改查 先建一个基本的 Spring Boot 项目开启 Spring B ...

  6. 2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(二)shiro权限注解 shiro注 ...

  7. Spring Boot 2.X(二):集成 MyBatis 数据层开发

    MyBatis 简介 概述 MyBatis 是一款优秀的持久层框架,支持定制化 SQL.存储过程以及高级映射.它采用面向对象编程的方式对数据库进行 CRUD 的操作,使程序中对关系数据库的操作更方便简 ...

  8. Spring Boot(十四):spring boot整合shiro-登录认证和权限管理

    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...

  9. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

随机推荐

  1. drf框架(2)

    drf框架 """接口: 接口规范: drf的生命周期: 序列化组件: 三大认证:过滤,删选,排序组件 请求,响应,解析,异常 jwt:json web tooken & ...

  2. wordpress更新出现Briefly unavailable for scheduled maintenance. Check back in a minute.

    今天ytkah在更新wordpress插件时出现了Briefly unavailable for scheduled maintenance. Check back in a minute.查找了相关 ...

  3. 学习Spring-Data-Jpa(十四)---自定义Repository

    有些时候,我们需要自定义Repository实现一些特殊的业务场景. 1.自定义单个Repository 1.1.首先提供一个片段接口和实现(接口的实现默认要使用Impl为后缀,实现本身不依赖spri ...

  4. S1_搭建分布式OpenStack集群_10 cinder 存储节点配置

    一.安装配置lvm2安装LVM包:# yum install -y lvm2 启动LVM元数据服务,并将其配置为在系统启动时启动:# systemctl enable lvm2-lvmetad.ser ...

  5. OKR的两个基本原则

    <启示录>作者,前易贝高级副总裁,硅谷产品集团创始人马蒂·卡根在<OKR工作法>的序言中提到了目标管理法的两个原则: 不要告诉下属具体怎么做,要告诉他们你要什么,他们就会给你满 ...

  6. 从TEB到PEB再到SEH(一)

    什么是TEB? TEB(Thread Environment Block,线程环境块) 线程环境块中存放着进程中所有线程的各种信息 这里我们了解到了TEB即为线程环境块, 进程中每一条线程都对应着的自 ...

  7. .NET API Gateway Ocelot 介绍

    项目:https://github.com/ThreeMammals/Ocelot  Windows (AppVeyor)  Linux & OSX (Travis)  Windows  Ma ...

  8. [bzoj1001]狼抓兔子 最小割

    题意概述:给出一张无向图,每条边有一个权值,割掉这条边代价为它的权值,求使起点不能到达终点的最小代价. 显然能看出这是个最小割嘛,然后最小割=最大流,建图的时候特殊处理一下再跑个最大流就好了. #in ...

  9. POJ 1436.Horizontally Visible Segments-线段树(区间更新、端点放大2倍)

    水博客,水一水. Horizontally Visible Segments Time Limit: 5000MS   Memory Limit: 65536K Total Submissions:  ...

  10. MSSQL手工注入 报错注入方法

    例子:www.kfgtfcj.gov.cn/lzygg/Zixun_show.aspx?id=1[1]首先爆版本:http://www.kfgtfcj.gov.cn/lzygg/Zixun_show. ...