上一篇文章,實現了用戶驗證 查看,接下來實現下權限控制
權限控制,是管理資源訪問的過程,用於對用戶進行的操作授權,證明該用戶是否允許進行當前操作,如訪問某個鏈接,某個資源文件等
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; } }
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
相關代碼 地址