一、前言
前段时间一直在研究如何通过标签方式控制控制的权限,我用HTML做页面的渲染,Shiro标签在HTML中不生效,但还是想用Shiro标签方式控制页面的按钮,有权限则显示,无权限则不显示,因此我想了一个替代方案来实现
二、方案描述
后端返回用户的所有角色及权限,前端自定义权限标签,通过标签中指定的权限与后端返回的权限做对比,有权限则按钮显示,无权限则按钮隐藏
PS:权限控制不仅是前端按钮的按钮,后端服务也要做控制,这里只介绍前端按钮的控制,后端权限控制请看另两篇博文《Shiro权限控制(二):自定义Filter》,《Shiro权限控制(三):Shiro注解权限验证》
三、自定义权限标签
user:hasPermission:权限标签,满足所有权限才能访问
例:<button user:hasPermission="USER:DELETE" type="button">删除用户</button>
表示有角色名称为USER的DELETE权限才能访问
user:hasRole:角色标签,满足所有角色才能访问
例:<p user:hasRole="USER"> 有 USER 角色权限</p>
表示有角色名称为USER的权限才能访问
user:hasAnyRoles:角色标签,只需要有指定角色中的任何一个就可以访问
例:<button user:hasAnyRoles="SALES,ADMINISTRATOR" type="button">超级管理员</button>
表示只需要有SALES或ADMINISTRATOR任何一个就可以访问
四、权限标签控制组件
自定义一个解析权限标签的公共组件user.permession.plugin.js,解析标签中指定的权限值,和后端返回的用户权限做对比,如果有权限,按钮显示,没有权限,删除按钮
$(function() {
$(document).ready(function(){
// 取用后端返回的用户权限数据
var userStr = window.sessionStorage.getItem("User");
var userData = JSON.parse(userStr);
// 权限数组,如 USER:DELETE,CUSTOMER_USER:ADD
var perArray = [];
// 角色数组,如 USER,ADMINISTRATOR
var roleArray = [];
for(var i = 0;i < userData.permessionList.length;i++){
perArray.push(userData.permessionList[i].permCodes);
roleArray.push(userData.permessionList[i].roleCode)
}
// 解析页面上所有的user:hasPermission 标签,如果没有权限,则删除页面元素
$('[user\\:hasPermission]').each(function(){
var permission = $(this).attr("user:hasPermission");
// 如果没有权限,则删除页面元素
if(-1 == $.inArray(permission,perArray)){
$(this).remove();
}
});
// 解析页面上所有的user:hasRole 标签,如果没有权限,则删除页面元素
$('[user\\:hasRole]').each(function(){
var role = $(this).attr("user:hasRole");
// 如果没有权限,则删除页面元素
if(-1 == $.inArray(role,roleArray)){
$(this).remove();
}
});
// 解析页面上所有的user:hasAnyRoles 标签,如果没有权限,则删除页面元素
$('[user\\:hasAnyRoles]').each(function(){
var hasRole = false;
var roles = $(this).attr("user:hasAnyRoles").split(",");
for(var i = 0;i < roles.length;i ++){
if(0 <= $.inArray(roles[i],roleArray)){
hasRole = true;
break;
}
}
// 如果没有权限,则删除页面元素
if(!hasRole){
$(this).remove();
}
});
});
});
五、验证
创建userManager.html页面,引入user.permession.plugin.js组件,在按钮中通过权限标签指定相应的权限码,用户登录成功后,自动跳转到此页面,有权限的按钮显示,没有权限的按钮不显示
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="../js/jquery/jquery-3.4.1.js"></script>
<script type="text/javascript" src="../js/jquery/jquery-migrate-1.4.1.js"></script>
<script type="text/javascript" src="../js/jquery/jquery-session.js"></script>
<script type="text/javascript" src="../js/user.permession.plugin.js"></script>
</head>
<body>
<button user:hasPermission="USER:DELETE" type="button">删除用户</button>
<button user:hasPermission="CUSTOMER_USER:ADD" type="button">新增用户</button>
<p user:hasRole="USER"> 有 USER 角色权限</p>
<button user:hasAnyRoles="SALES,CUSTOMER_USER" type="button">用户管理</button>
<button user:hasAnyRoles="SALES,ADMINISTRATOR" type="button">超级管理员</button>
</body>
</html>
登录页面,登录成功后,获得后端返回的用户权限数据,并保存到sessionStorage中,然后跳转到userManager.html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery/jquery-3.4.1.js"></script>
<script type="text/javascript" src="js/jquery/jquery-migrate-1.4.1.js"></script>
<script type="text/javascript" src="js/jquery/jquery-session.js"></script>
<script type="text/javascript" src="login.js"></script>
</head>
<body>
用户名:<input id="userName" type="text" name="userName"><br/>
密码:<input id="password" type="password" name="password"><br/>
<input id="login" type="submit" value="登录">
</body>
</html>
登录页面对应的JS
$(function() {
$(document).ready(function(){
bindEvent();
});
function bindEvent(){
$("#login").bind("click",login);
}
function login(){
var data = {
userName:$("#userName").val(),
password:$("#password").val()
}
var request = $.ajax({
cache : false,
async : false,
url : "/bug.web/user/checkLogin",
contentType : "application/json; charset=utf-8",
method : "post",
data : JSON.stringify(data, null, ""),
dataType : 'json'
});
request.done(function(data) {
if(data.status == "0"){
// 将用户信息保存到全局变量中
window.sessionStorage.setItem("User",JSON.stringify(data.data, null, ""));
window.location.href = "/bug.web/html/user/userManager.html";
}else{
alert(data.message);
}
});
}
});
登录成功后,看页面显示效果,页面上只显示新增用户和用户管理两个按钮,其他没权限的按钮不显示