RBAC实战

一、 什么是 RBAC

RBAC(Role-Based Access Control )基于角色的访问控制。
RBAC 认为权限的过程可以抽象概括为:
判断【Who 是否可以对 What 进行 How 的访问操作(Operator)】
Who:权限的拥用者或主体
What:权限针对的对象或资源
How:具体的权限
Operator:操作。表明对 What 的 How 操作。也就是 Privilege+Resource
Role:角色,一定数量的权限的集合。权限分配的单位与载体,目的是隔离User与Privilege 的逻辑关系

二、 RBAC96 模型

1 RBAC 模型

RBAC96 模型家族,其中包括了 RBAC0~RBAC3 四个概念模型。
在这里插入图片描述

2 RBAC0

定义了能构成一个 RBAC 控制系统的最小的元素集合

在 RBAC 之中,包含用户 users(USERS)、角色 roles(ROLES)、目标 objects(OBS)、操作 operations(OPS)、许可权 permissions(PRMS)五个基本数据元素,权限被赋予角色,而不是用 户,当一个角色被指定给一个用户时,此用户就拥有了该角色所包含的权限。会话 sessions 是用户与激活的角色集合之间的映射。RBAC0 与传统访问控制的差别在于增加一层间接性 带来了灵活性,RBAC1、 RBAC2、RBAC3 都是先后在 RBAC0 上的扩展。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
UA(User Assignment):用户角色分配
PA(Permission Assignment):角色许可分配

3 RBAC1

引入角色间的继承关系

角色间的继承关系可分为一般继承关系和受限继承关系。一般继承关系仅要求角色继承 关系是一个绝对偏序关系,允许角色间的多继承。而受限继承关系则进一步要求角色继承关 系是一个树结构
在这里插入图片描述

4 RBAC2

该模型中添加了责任分离关系

RBAC2 的约束规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻 激活一个角色时所应遵循的强制性规则。责任分离包括静态责任分离和动态责任分离。约束 与用户-角色-权限关系一起决定了 RBAC2 模型中用户的访问许可
在这里插入图片描述

5 RBAC3

RBAC3 包含了 RBAC1 和 RBAC2

既提供了角色间的继承关系,又提供了责任分离关系
在这里插入图片描述

三、 RBAC 实战

1 需求

1)实现用户登录功能
2)使用 RBAC0 模型管理系统权限
3)对系统的菜单以及菜单中的链接进行管理。
4)用户登录后首页根据用户角色显示该角色所对应的菜单
5)禁止用户越级访问

2 技术选择

1)框架:SpringMVC+Spring+Mybatis
2)数据库:Mysql

3 数据库设计

在这里插入图片描述

4 创建表

4.1创建用户表

CREATE TABLE `users` ( 
	`username` varchar(50) NOT NULL, 
	`userpwd` varchar(50) DEFAULT NULL, 
	`role_id` int(11) DEFAULT NULL,
	PRIMARY KEY (`username`), 
	KEY `users_fk` (`role_id`), 
	CONSTRAINT `users_fk` FOREIGN KEY (`role_id`) REFERENCES `roles` (`roleid`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.2创建角色表

CREATE TABLE `roles` ( 
	`roleid` int(11) NOT NULL AUTO_INCREMENT, 
	`rolename` varchar(50) DEFAULT NULL, 
	PRIMARY KEY (`roleid`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.3创建菜单表

CREATE TABLE `menus` ( 
	`menuid` int(11) NOT NULL AUTO_INCREMENT,
	`menuname` varchar(50) DEFAULT NULL, 
	`menuurl` varchar(50) DEFAULT NULL, 
	`fatherid` int(11) DEFAULT NULL, 
	PRIMARY KEY (`menuid`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.4创建功能表

CREATE TABLE `funs` ( 
	`funid` int(11) NOT NULL AUTO_INCREMENT, 
	`funname` varchar(50) DEFAULT NULL, 
	`funurl` varchar(50) DEFAULT NULL, 
	`menu_id` int(11) DEFAULT NULL, 
	PRIMARY KEY (`funid`), 
	KEY `menus_fk` (`menu_id`), 
	CONSTRAINT `menus_fk` FOREIGN KEY (`menu_id`) REFERENCES `menus` (`menuid`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.5创建菜单角色中间表

CREATE TABLE `roles_menus` ( 
	`roles_id` int(11) NOT NULL, 
	`menus_id` int(11) NOT NULL, 
	PRIMARY KEY (`roles_id`,`menus_id`), 
	KEY `roles_menus_fk2` (`menus_id`), 
	CONSTRAINT `roles_menus_fk1` FOREIGN KEY (`roles_id`) REFERENCES `roles` (`roleid`), 
	CONSTRAINT `roles_menus_fk2` FOREIGN KEY (`menus_id`) REFERENCES `menus` (`menuid`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

四、 动态菜单实现

1 添加基础数据

1.1菜单介绍

在这里插入图片描述

1.2录入菜单基础数据

在这里插入图片描述

1.3录入角色基础数据

在这里插入图片描述

1.4录入用户基础数据

在这里插入图片描述

1.5角色关联菜单

在这里插入图片描述

2 框架整合

2.1创建工程

在这里插入图片描述

2.2添加 jar 包

在这里插入图片描述

2.3框架整合

在这里插入图片描述

2.4访问首页

在这里插入图片描述

3 创建 POJO 与 Mapper

3.1创建 POJO

3.1.1 Users

package com.bjsxt.pojo;

import java.util.ArrayList;
import java.util.List;

public class Users {
    
    
	private String username;
	private String userpwd;
	private Roles roles;
	
	public Roles getRoles() {
    
    
		return roles;
	}
	public void setRoles(Roles roles) {
    
    
		this.roles = roles;
	}
	public String getUsername() {
    
    
		return username;
	}
	public void setUsername(String username) {
    
    
		this.username = username;
	}
	public String getUserpwd() {
    
    
		return userpwd;
	}
	public void setUserpwd(String userpwd) {
    
    
		this.userpwd = userpwd;
	}
	
}

3.1.2 Roles

package com.bjsxt.pojo;

import java.util.ArrayList;
import java.util.List;

public class Roles {
    
    
	private int roleid;
	private String rolename;
	private List<Menus> menus = new ArrayList<>();
	
	public List<Menus> getMenus() {
    
    
		return menus;
	}
	public void setMenus(List<Menus> menus) {
    
    
		this.menus = menus;
	}
	public int getRoleid() {
    
    
		return roleid;
	}
	public void setRoleid(int roleid) {
    
    
		this.roleid = roleid;
	}
	public String getRolename() {
    
    
		return rolename;
	}
	public void setRolename(String rolename) {
    
    
		this.rolename = rolename;
	}
	
}

3.1.3 Menus

package com.bjsxt.pojo;

import java.util.ArrayList;
import java.util.List;

public class Menus {
    
    

	private int menuid;
	private String menuname;
	private String menuurl;
	private int fatherid;
	private List<Funs> funs = new ArrayList<>();
	
	public List<Funs> getFuns() {
    
    
		return funs;
	}
	public void setFuns(List<Funs> funs) {
    
    
		this.funs = funs;
	}
	public int getMenuid() {
    
    
		return menuid;
	}
	public void setMenuid(int menuid) {
    
    
		this.menuid = menuid;
	}
	public String getMenuname() {
    
    
		return menuname;
	}
	public void setMenuname(String menuname) {
    
    
		this.menuname = menuname;
	}
	public String getMenuurl() {
    
    
		return menuurl;
	}
	public void setMenuurl(String menuurl) {
    
    
		this.menuurl = menuurl;
	}
	public int getFatherid() {
    
    
		return fatherid;
	}
	public void setFatherid(int fatherid) {
    
    
		this.fatherid = fatherid;
	}
	
}

3.1.4Funs

package com.bjsxt.pojo;

public class Funs {
    
    
	
	private int funid;
	private String funname;
	private String funurl;
	
	public int getFunid() {
    
    
		return funid;
	}
	public void setFunid(int funid) {
    
    
		this.funid = funid;
	}
	public String getFunname() {
    
    
		return funname;
	}
	public void setFunname(String funname) {
    
    
		this.funname = funname;
	}
	public String getFunurl() {
    
    
		return funurl;
	}
	public void setFunurl(String funurl) {
    
    
		this.funurl = funurl;
	}
}

3.2 创建 Mapper

3.2.1 创建接口

public interface UsersMapper {
    
     
	Users selectUserByName(String username);
 }

3.2.2 创建映射配置文件

<?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.bjsxt.mapper.UsersMapper" >
	
	<resultMap type="com.bjsxt.pojo.Users" id="userMapper">
		<id property="username" column="username"/>
		<result property="userpwd" column="userpwd"/>
		<!-- 配置关联对象Roles -->
		<association property="roles" javaType="com.bjsxt.pojo.Roles">
			<id property="roleid" column="roleid"/>
			<result property="rolename" column="rolename"/>
		</association>
		<!-- 配置关联对象Menus -->
		<collection property="menus" ofType="com.bjsxt.pojo.Menus">
			<id property="menuid" column="menuid"/>
			<result property="menuname" column="menuname"/>
			<result property="menuurl" column="menuurl"/>
			<result property="fatherid" column="fatherid"/>
		</collection>
		
	</resultMap>

	<select id="selectUserByName" parameterType="string" resultMap="userMapper">
		select * from users u ,roles r ,roles_menus rm ,menus m where u.role_id = r.roleid and r.roleid = rm.roles_id and rm.menus_id = m.menuid and u.username =#{username}
	</select>
</mapper>

4 编写用户登录业务层代码

4.1 业务层接口

package com.bjsxt.service;

import com.bjsxt.pojo.Users;

public interface UserService {
    
    

	Users userLogin(String username,String userpwd);
}

4.2 接口实现类

package com.bjsxt.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bjsxt.exception.UsersException;
import com.bjsxt.mapper.UsersMapper;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;

@Service
public class UserServiceImpl implements UserService{
    
    

	@Autowired
	private UsersMapper usersMapper;
	
	/**
	 * 用户登录
	 */
	@Override
	public Users userLogin(String username, String userpwd) {
    
    
		Users users = this.usersMapper.selectUserByName(username);
		if(users == null){
    
    
			//用户不存在
			throw new UsersException("用户不存在或密码有误");
		}else if(!users.getUserpwd().equals(userpwd)){
    
    
			//密码有误
			throw new UsersException("用户不存在或密码有误");
		}
		return users;
	}
}

自定义异常:UsersException

package com.bjsxt.exception;

public class UsersException extends RuntimeException {
    
    

	public UsersException() {
    
    

	}
	public UsersException(String msg) {
    
    
		super(msg);
	}

	public UsersException(String msg, Throwable t) {
    
    
		super(msg, t);
	}
}

5 编写用户登录 Controller

5.1创建 login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3><font color="red">${
    
    requestScope.msg }</font></h3>
	<form action="userLogin" method="post">
		用户名<input type="text"  name="username"/><br/>
		密码<input type="password"  name="userpwd"/><br/>
		<input type="submit" value="OK"/><br/>
	</form>
</body>
</html>

5.2 创建 LoginController

package com.bjsxt.web.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.bjsxt.exception.UsersException;
import com.bjsxt.pojo.Funs;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;

@Controller
public class LoginController {
    
    
	
	@Autowired
	private UserService userService;

	@RequestMapping("/userLogin")
	public String userLogin(Users users,Model model,HttpServletRequest request){
    
    
		try{
    
    
			Users u = this.userService.userLogin(users.getUsername(), users.getUserpwd());
			HttpSession session = request.getSession();
			session.setAttribute("user", u);
		}catch(UsersException e){
    
    
			e.printStackTrace();
			model.addAttribute("msg", e.getMessage());
			return "/login";
		}
		return "redirect:/index";
	}
}

6 页面布局

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<frameset rows="15%,*,10%" border="1">
<frame src="head" scrolling="no" name="head">
<frameset cols="20%,*">
	<frame src="menu" scrolling="auto" name="menu">
	<frame src="body" scrolling="auto" name="body">
</frameset>
<frame src="foot" scrolling="auto" name="foot">
</html>

在这里插入图片描述

7 Dtree 介绍

在这里插入图片描述

8 显示菜单

menu.jsp

<%@page import="com.bjsxt.pojo.Menus"%>
<%@page import="java.util.List"%>
<%@page import="com.bjsxt.pojo.Users"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
    <SCRIPT language=javascript src="js/dtree/dtree.js"></SCRIPT>
    <script type="text/javascript" src="js/java-like.util.js"></script>
    <link rel="stylesheet" href="js/dtree/dtree.css" type="text/css">
</head>
<body>
	<form action="" name="form1" method=POST>
    <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
            <td rowspan="5" width="1" bgcolor="CCCCCC"></td>
            <td bgcolor="CCCCCC" height="1"></td>
            <td rowspan="4" bgcolor="CCCCCC" width="1"></td>
        </tr>

        <tr>
            <td bgcolor="E3E7FF" align="center" height="5"></td>
        </tr>

        <tr>
            <td bgcolor="CCCCCC" height="1"></td>
        </tr>

        <tr>
            <td bgcolor="F9F9F9" align="center" valign="top">
                <table width="90%" border="0" align="center" cellpadding="1" cellspacing="1" bgcolor="F5F5F5">
                    <tr bgcolor="F3F9FF">
                        <td bgcolor="F5F5F5">
                            <SCRIPT LANGUAGE="JavaScript">
                                d = new dTree('d');
                                d.config.target = "body";
                                d.config.imageDir = 'js/dtree/img';
                                d.reSetImagePath();
                                d.config.folderLinks = false;
                                d.config.closeSameLevel =true;
                                var isOpen ;
                                //根节点
								<%
									Users user = (Users)session.getAttribute("user");
                                List menus = user.getMenus();
                                for(int i=0;i<menus.size();i++){
    
    
                                	Menus menu = (Menus)menus.get(i);
								%>
                                d.add(<%=menu.getMenuid() %>, <%=menu.getFatherid() %>, '<%=menu.getMenuname() %>', '<%=menu.getMenuurl() %>', '', 'body');
								<%}%>
                                document.write(d);
                            </script>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>

        <tr>
            <td background="images/jao1.gif" colspan="2" align="right"><img
                    src="images/jao.gif" width="8" height="8"></td>
        </tr>

    </table>
</form>
</body>
</html>

Admin 用户
在这里插入图片描述
Zhagnsan 用户
在这里插入图片描述

9 用户登录过滤器

9.1创建 Filter

package com.bjsxt.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.bjsxt.pojo.Users;
/**
 * 判断用户是否登录
 * @author Administrator
 *
 */
public class UserLoginFilter implements Filter {
    
    

	@Override
	public void destroy() {
    
    
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
			throws IOException, ServletException {
    
    
		//获取用户访问的URI
		HttpServletRequest req = (HttpServletRequest)arg0;
		String uri = req.getRequestURI();
		
		//判断当前访问的URI是否是用户登录资源,如果是则放行
		if(uri.indexOf("login") != -1 || uri.indexOf("userLogin") != -1){
    
    
			chain.doFilter(arg0, arg1);
		}else{
    
    
			//用户是否登录的判断
			HttpSession session = req.getSession();
			Users user = (Users)session.getAttribute("user");
			if(user != null && user.getUsername().length() > 0){
    
    
				chain.doFilter(arg0, arg1);
			}else{
    
    
				req.setAttribute("msg", "请登录");
				req.getRequestDispatcher("/login").forward(arg0, arg1);
			}
		}
		
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
    
    
		// TODO Auto-generated method stub

	}

}

9.2配置 Filter

<filter>
		<filter-name>UserLoginFilter</filter-name>
		<filter-class>com.bjsxt.web.filter.UserLoginFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>UserLoginFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

五、 权限管理

1 越级访问

所谓的越级访问就是使用低级别的角色访问高级别的资源
在这里插入图片描述

2 录入资源管理基础数据

在这里插入图片描述
在这里插入图片描述

3 查询资源

3.1修改 User 实体类添加与 Funs 的关联

package com.bjsxt.pojo;

import java.util.ArrayList;
import java.util.List;

public class Users {
    
    
	private String username;
	private String userpwd;
	private Roles roles;
	private List<Menus> menus = new ArrayList<Menus>();
	private List<Funs> funs = new ArrayList<>();
	public List<Funs> getFuns() {
    
    
		return funs;
	}
	public void setFuns(List<Funs> funs) {
    
    
		this.funs = funs;
	}
	public List<Menus> getMenus() {
    
    
		return menus;
	}
	public void setMenus(List<Menus> menus) {
    
    
		this.menus = menus;
	}
	public Roles getRoles() {
    
    
		return roles;
	}
	public void setRoles(Roles roles) {
    
    
		this.roles = roles;
	}
	public String getUsername() {
    
    
		return username;
	}
	public void setUsername(String username) {
    
    
		this.username = username;
	}
	public String getUserpwd() {
    
    
		return userpwd;
	}
	public void setUserpwd(String userpwd) {
    
    
		this.userpwd = userpwd;
	}
	
}

3.2修改 Sql 语句

SELECT 
 * 
FROM
	users u, 
	roles r, 
	roles_menus rm, 
	menus m left JOIN funs f ON m.menuid = f.menu_id 
WHERE 
	u.role_id = r.roleid 
	AND r.roleid = rm.roles_id 
	AND rm.menus_id = m.menuid 
	AND u.username = 'admin

3.3修改 ResultMap

<?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.bjsxt.mapper.UsersMapper" >
	
	<resultMap type="com.bjsxt.pojo.Users" id="userMapper">
		<id property="username" column="username"/>
		<result property="userpwd" column="userpwd"/>
		<!-- 配置关联对象Roles -->
		<association property="roles" javaType="com.bjsxt.pojo.Roles">
			<id property="roleid" column="roleid"/>
			<result property="rolename" column="rolename"/>
		</association>
		<!-- 配置关联对象Menus -->
		<collection property="menus" ofType="com.bjsxt.pojo.Menus">
			<id property="menuid" column="menuid"/>
			<result property="menuname" column="menuname"/>
			<result property="menuurl" column="menuurl"/>
			<result property="fatherid" column="fatherid"/>
		</collection>
		<!-- 配置关联对象Funs -->
		<collection property="funs" ofType="com.bjsxt.pojo.Funs">
			<id property="funid" column="funid"/>
			<result property="funname" column="funname"/>
			<result property="funurl" column="funurl"/>
		</collection>
	</resultMap>

	<select id="selectUserByName" parameterType="string" resultMap="userMapper">
		SELECT
				*
			FROM
				users u,
				roles r,
				roles_menus rm,
				menus m left JOIN funs f ON m.menuid = f.menu_id
			WHERE
				u.role_id = r.roleid
			AND r.roleid = rm.roles_id
			AND rm.menus_id = m.menuid
			AND u.username = #{username}
	</select>
</mapper>

4 权限过滤器

4.1修改 Funs 表中的基础数据

在这里插入图片描述

4.2创建权限过滤器

package com.bjsxt.web.filter;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.bjsxt.pojo.Funs;
import com.bjsxt.pojo.Users;
/**
 * 权限过滤器
 * @author Administrator
 *
 */
public class SafeFilter implements Filter {
    
    

	@Override
	public void destroy() {
    
    
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
			throws IOException, ServletException {
    
    
		HttpServletRequest req = (HttpServletRequest)arg0;
		HttpServletResponse res = (HttpServletResponse)arg1;
		String uri = req.getRequestURI();
		//对静态资源做放行处理
		if(uri.endsWith(".js") || uri.endsWith(".css")|| uri.endsWith(".gif")){
    
    
			chain.doFilter(arg0, arg1);
		}else{
    
    
			//对用户登录资源做放行
			if(uri.indexOf("login") != -1 || uri.indexOf("userLogin") != -1){
    
    
				chain.doFilter(arg0, arg1);
			}else{
    
    
				HttpSession session = req.getSession();
				Users user = (Users)session.getAttribute("user");
				List<Funs> funs = user.getFuns();
				//开关
				boolean flag = false;
				for(Funs f:funs){
    
    
					//判断当前访问的URI是否在功能数据中包含
					if(uri.indexOf(f.getFunurl()) != -1){
    
    
						flag = true;
						break;
					}
				}
				//根据开关的值来进行跳转
				if(flag){
    
    
					chain.doFilter(arg0, arg1);
				}else{
    
    
					res.sendRedirect("roleerror");
				}
			}
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
    
    
		// TODO Auto-generated method stub

	}

}

4.3在 web.xml 文件中配置过滤器

	<filter>
		<filter-name>SafeFilter</filter-name>
		<filter-class>com.bjsxt.web.filter.SafeFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>SafeFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

项目源码:https://gitee.com/cutelili/rbac
下一篇:【Shiro】

猜你喜欢

转载自blog.csdn.net/qq_42588990/article/details/121103505