勿以恶小而为之,勿以善小而不为--------------------------刘备

劝诸君,多行善事积福报,莫作恶

上一章简单介绍了 Servlet实现RBAC权限管理(二) ,如果没有看过,​​请观看上一章​​

在学习这一章节之前,一定要观看上一章节的内容,代码和思路,与上一章节类似,也需要掌握 SSM框架的相应知识。

如果不了解 SSM框架的相应知识,可以观看 老蝴蝶以前写的文章。

一. 准备阶段

一.一 数据库准备阶段

准备与上一章节的数据库结构和内容都一样,只是将权限表 privilege 的url 地址改变了一下,由 servlet 访问路径改变成了 springmvc 访问路径。

SSM实现权限管理(三)_SSM实现权限管理

一.二 SSM框架搭建和前端页面

SSM框架,采用 Maven 方式进行搭建,所用到依赖和配置文件,均采用SSM整合时的内容,

详细可以看: ​​Maven整合SSM项目(七)​​

页面也采用上一章节的页面信息。

框架搭建后的目录结构如图所示:

SSM实现权限管理(三)_登录拦截器_02

二. 权限认证

二.一 认证和授权

二.一.一 认证

二.一.一.一 认证的 前端js 页面

html 页面:

SSM实现权限管理(三)_SSM实现权限管理_03

脚本代码:

$(function(){
$("#submit").click(function(){
var code=$("#code").val();
var password=$("#password").val();

var info=new Object();
//传入进去,员工的id编号
info.code=code;
info.password=password;

$.post("${pageContext.request.contextPath}/User/login",info,function(data){
if(data.response_status){
alert("登录成功");
window.location.href="${pageContext.request.contextPath}/Main/toMain";
}else{
if(data.error_msg=="001"){
alert("用户名或者密码错误");
}
}
},"json")

})
})

二.一.一.二 后端登录处理

在 UserAction 下面的 login() 方法里面。

@RequestMapping("/login")
@ResponseBody
public Map<String,Object> login(User userInfo,HttpSession session){
//将请求信息,封装到对象里面。
Map<String,Object> map=new HashMap<String,Object>();
//从数据库中查询密码
User user=userService.login(userInfo);

if(user!=null){
//说明登录成功,放置到session里面
session.setAttribute("loginUser",user);

//查询一下,该员工的 按钮权限信息。
List<Privilege> privilegeList= privilegeService.getPrivilegeByUId(user.getId(),2);

List<String> priCodeList=new ArrayList<String>();
for(Privilege pri:privilegeList){
if(pri.getPercode()!=null){
//放置标识
priCodeList.add(pri.getPercode());
}

}
//将权限转换成 json 字符串
ObjectMapper objMapper=new ObjectMapper();
Map<String,List<String>> priCodeMap=new HashMap<String,List<String>>();
priCodeMap.put("data", priCodeList);
String priValueString="";
try {
priValueString = objMapper.writeValueAsString(priCodeMap);
} catch (JsonProcessingException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
session.setAttribute("privilegeList",priValueString);

//登录成功
map.put("response_status", true);

}else{
//代码为001,表示用户名或者密码错误
map.put("response_status", false);
map.put("error_code","101");
}

return map;

}

二.一.二 授权

二.一.二.一 左侧菜单展示

1.html 页面元素

SSM实现权限管理(三)_SSM实现权限管理_04

2.js 脚本处理

SSM实现权限管理(三)_权限管理_05

3.后端的 Mapper 查询, 在 PrivilgeMapper.xml 里面。

<select id="findByUid" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from privilege a where a.id in (
select rp.pid from user_role ur left join role_privilege rp
on ur.rid=rp.rid
where ur.uid=#{uId,jdbcType=INTEGER}
)
<if test="type != null and type !=''" >
and a.type=#{type,jdbcType=INTEGER}
</if>
</select>

二.一.二.二 部门表按钮显示

与前面是一致的.

1 . 设置标识

<script>
//获取权限
var privilegeList='<%=session.getAttribute("privilegeList")%>';
//console.log("值是:"+privilegeList+","+typeof(privilegeList));
var objPrivilegeList=JSON.parse(privilegeList);
$.each(objPrivilegeList.data,function(idx,item){
//将标识存放在 sessionStorage 里面,进行暂时的保存。
sessionStorage.setItem(item,true);
})
</script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/dept.js"></script>

2 . 通过标识,对部门表的按钮元素进行显示或者隐藏

SSM实现权限管理(三)_权限管理_06

二.二 权限验证测试

通过对 admin,yuejl,yuezl 三个不同的角色进行登录,可以正常地相应的菜单权限和按钮权限。

也同样,需要处理过滤器,只是在 SpringMVC 里面,叫做拦截器。

关于拦截器的使用,可以看老蝴蝶以前写得文章: ​​SpringMVC的拦截器(十四)​​

二.三. 登录和授权拦截器

二.三.一 编写拦截器 LoginInterceptor

package com.yjl.action;

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

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.yjl.pojo.Privilege;
import com.yjl.pojo.User;
import com.yjl.service.PrivilegeService;
/**
*
* @author 两个蝴蝶飞
*
* 登录和授权拦截器
*/
public class LoginInterceptor implements HandlerInterceptor{

@Autowired
private PrivilegeService privilegeService;
//不需要登录验证的url
private static List<String> noLoginValidateUrl;
//不需要权限验证的url
private static List<String> noPriValidateUrl;

//跳转到的登录页面
private static String LOGIN_URL;
//没有权限的界面
private static String NO_PRIVILEGE_URL;

static{
noLoginValidateUrl=new ArrayList<String>();

//静态资源
noLoginValidateUrl.add("/static/");
//登录页面
noLoginValidateUrl.add("/User/toLogin");
//登录方法
noLoginValidateUrl.add("/User/login");


noPriValidateUrl=new ArrayList<String>();

noPriValidateUrl.add("/Main/toMain");
//查询权限


noPriValidateUrl.add("/Privilege/getPrivilegeByUId");
//退出
noPriValidateUrl.add("/User/logout");

LOGIN_URL="/WEB-INF/jsp/login.jsp";

NO_PRIVILEGE_URL="/WEB-INF/jsp/noPrivilege.jsp";
}


@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO 自动生成的方法存根

}

@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
// TODO 自动生成的方法存根

}

@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object arg2) throws Exception {

//获取Session
HttpSession session=req.getSession();

//请求路径
String realPath=req.getRequestURI();
System.out.println("地址是:"+realPath);

//验证是否在 不需要验证登录的url里面
if(isContain(realPath,1)){
return true;
}
//如果为空,表示没有登录
if(session.getAttribute("loginUser")==null){
req.getRequestDispatcher(LOGIN_URL).forward(req,resp);
return false;
}else{

//不需要验证权限
if(isContain(realPath,2)){
return true;
}
//如果不为空,表示登录了。
//重新获取全部权限 , 需要缓存, 这儿不用缓存。
User user=(User)session.getAttribute("loginUser");
List<Privilege> privilegeList=privilegeService.getPrivilegeByUId(user.getId(),null);
if(privilegeList!=null&&privilegeList.size()>0){
boolean isHavePri=false;
for(Privilege pri:privilegeList){
if(pri.getUrl()!=null){
if(realPath.contains(pri.getUrl())){
isHavePri=true;
break;
}
}
}
if(isHavePri){
//放行
return true;
}else{
req.getRequestDispatcher(NO_PRIVILEGE_URL).forward(req,resp);
return false;
}
}
return false;

}

}
private boolean isContain(String realPath,int type){
List<String> urls;
if(type==1){
urls=noLoginValidateUrl;
}else{
urls=noPriValidateUrl;
}

boolean flag=false;

for(String url:urls){
//包括,返回-1
if(realPath.indexOf(url)!=-1){
flag=true;
break;
}
}
return flag;

}
}

二.三.二 配置拦截器

在springmvc.xml 配置文件中进行配置

SSM实现权限管理(三)_不同用户权限管理_07

按照上一章节的方式进行测试,发现测试正确,不同的用户具有不同的角色,老蝴蝶这儿就不再次贴图了。

本章节的代码链接为:

链接:https://pan.baidu.com/s/1PChrWK9l02ANccerzc7rsg 
提取码:iwvj

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!