北京尚学堂2020java_RBAC
第一节 RBAC简介
基于角色的权限访问控制,是一个数据库设计思想,根据数据库设计方案,完成项目的权限控制。
第二节 传统项目数据库设计方案
会建议用户-权限表,每新增一个用户,会增加一大堆东西。
第三节 RBAC设计方案
为了管理好用户-权限,新增一个“角色”表。一个角色对应一些权限,而用户会对应一些角色,这样就把一对多拆开来了,解决了冗余问题。
第四节 RBAC代码示例
##创建用户信息表
create table t_user(
uid int(10) not null auto_increment,
uname varchar(100) not null,
pwd varchar(100) not null,
rid int(10),
PRIMARY key(uid)
);
##创建角色信息表
create table t_role(
rid int(10) not null auto_increment,
rname varchar(100) not null,
rdesc varchar(200),
PRIMARY key(rid)
);
##创建菜单信息表
create table t_menu(
mid int(10) not null auto_increment,
mname varchar(100) not null,
murl varchar(100),
parentid int(10) not null,
mdesc varchar(200),
PRIMARY key(mid)
);
##创建角色菜单中间表
create table r_menu(
rid int(10) not null,
mid int(10) not null
);
##添加用户测试数据
insert into t_user values(default,'张三','123',1);
insert into t_user values(default,'李四','456',2);
##添加角色测试数据
insert into t_role values(default,'人事经理','管理用户信息');
insert into t_role values(default,'管理员','可以操作所有的菜单');
##添加菜单测试数据
##添加一级菜单信息
insert into t_menu values(default,'用户管理','',0,'一级菜单');
insert into t_menu values(default,'班级管理','',0,'一级菜单');
insert into t_menu values(default,'查看通告','',0,'一级菜单');
insert into t_menu values(default,'系统设置','',0,'一级菜单');
##添加二级菜单信息
insert into t_menu values(default,'用户查询','',1,'二级菜单');
insert into t_menu values(default,'增加用户','',1,'二级菜单');
insert into t_menu values(default,'班级查询','',2,'二级菜单');
insert into t_menu values(default,'增加班级','',2,'二级菜单');
##添加角色菜单测试数据
insert into r_menu values(1,1);
insert into r_menu values(1,5);
insert into r_menu values(1,6);
insert into r_menu values(2,1);
insert into r_menu values(2,2);
insert into r_menu values(2,3);
insert into r_menu values(2,4);
insert into r_menu values(2,5);
insert into r_menu values(2,6);
insert into r_menu values(2,7);
insert into r_menu values(2,8);
第五节 RBAC详细版本
第六节 权限控制
一切用户可以通过url直接访问到对应的jsp,这样是不安全的,应该加上一层过滤器。
package com.bjsxt.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
@WebFilter("/*")
public class TruePowerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//过滤器的拦截方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1.获取当前用户的请求地址
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
String requestURI = request.getRequestURI();
System.out.println("当前请求的uri地址信息:"+requestURI);
// 公共资源放行
if(requestURI.endsWith("login.jsp") || requestURI.endsWith("userLogin") ||requestURI.endsWith("main.jsp")
|| requestURI.endsWith("power.jsp") || requestURI.endsWith(".js") || requestURI.endsWith(".css") ||
requestURI.contains("images")
){
filterChain.doFilter(servletRequest,servletResponse);
return;
}
//校验session是否失效
//获取session对象
HttpSession session = request.getSession();
//获取session中存储的登录成功的用户信息
User user= (User) session.getAttribute("user");
//校验
if(user==null){//session失效
//判断当前请求是否为ajax请求
if(request.getHeader("x-requested-with") !=null && request.getHeader("x-requested-with").equals("XMLHttpRequest")){
//直接响应ajax请求
response.getWriter().write("sessionError");
return;
}
//重定向到登录页面让用户重新进行登录
response.sendRedirect(request.getContextPath()+"/login.jsp");
return;
}
//放行menuInfo请求
if(requestURI.endsWith("menuInfo")){
filterChain.doFilter(servletRequest,servletResponse);
return;
}
//2.从session中获取当前用户能够访问的url地址列表(用户登录成功将该用户的url地址信息存储到session中)
//获取用户的url地址
List<Url> urls = (List<Url>) session.getAttribute("urls");
//3.判断用户的url地址信息是否合法
if(urls!=null){
for(Url url:urls){
if(requestURI.contains(url.getUrl())){
System.out.println("当前请求放行的资源地址"+requestURI+":"+url.getUrl());
//放行
filterChain.doFilter(servletRequest,servletResponse);
return;
}
}
}
//4.重定向到权限提示页面
response.sendRedirect(request.getContextPath()+"/power.jsp");
return;
}
@Override
public void destroy() {
}
}