话不多说,先上流程图
最主要的就是拦截器,在页面请求开始前判断权限-》执行请求-》返回请求页面的权限按钮控制
下面我们看下请求前哦
/// <summary>
/// 重写 在调用操作方法前调用
/// </summary>
/// <param name="filterContext"></param>
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
UserInfo ui = GetSessionUserInfo();
//判断是否登录
if (ui == null)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 520;
MsgHelper msg = new MsgHelper();
msg.flag = 98;
msg.msg = "/Login/Login?returnUrl=" + Request.Url.PathAndQuery;
filterContext.Result = new JsonResult() { Data = msg };
}
else
{
filterContext.Result = new RedirectResult("/Login/Login?returnUrl=" + Request.Url.PathAndQuery);
}
return;
}
else if (ui.iState == 1)
{
//没有权限访问
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 520;
MsgHelper msg = new MsgHelper();
msg.flag = 99;
msg.msg = "没有权限,请联系管理员";
filterContext.Result = new JsonResult() { Data = msg };
}
else
{
filterContext.Result = new ContentResult() { Content = @"
<!DOCTYPE html>
<script src='../../../layui/layui.all.js'></script>
<script>
parent.layer.open({
title: '提示',
content: '没有权限,请联系管理员'
});
</script>" };
// filterContext.Result = Content("<script>alert('没有权限,请联系管理员');window.opener=null;window.close();</script>");
}
return;
}
//判断是否有权限访问
string controllerName = (filterContext.RouteData.Values["controller"]).ToString().ToLower();
string actionName = (filterContext.RouteData.Values["action"]).ToString().ToLower();
string path = Request.Url.AbsolutePath.ToLower();
string pathLast = path.Split('/').Last();//判断是否没有输入全,由路由规则自动补全路径
if (path == "")
{
path = "/" + controllerName + "/" + actionName;
}
else if (pathLast == "")
{
path = path + controllerName + "/" + actionName;
}
else if (pathLast == controllerName)
{
path = path + "/" + actionName;
}
Menu m = SysCache.MenuList.Where(p => p.sHref.ToLower() == path).FirstOrDefault();
if (m != null)//判断请求页面或功能是否在菜单表中 在-》判断是否有权限 不在-》跳过
{
var list = SysCache.RoleMenuList.Where(p => ui.sRoleKey.ToLower().Contains(p.gRoleKey.ToString()));
foreach (var item in list)
{
if (item.gMenuKey.ToString() == m.gKey.ToString())//角色权限 菜单主键与请求菜单主键相同 表示有权限访问
{
return;
}
}
//没有权限访问
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 520;
MsgHelper msg = new MsgHelper();
msg.flag = 99;
msg.msg = "没有权限,请联系管理员";
filterContext.Result = new JsonResult() { Data = msg };
}
else
{
filterContext.Result = new ContentResult() { Content = @"
<!DOCTYPE html>
<script src='../../../layui/layui.all.js'></script>
<script>
parent.layer.open({
title: '提示',
content: '没有权限,请联系管理员'
});
</script>" };
// filterContext.Result = Content("<script>alert('没有权限,请联系管理员');window.opener=null;window.close();</script>");
}
return;
}
}
首页我们判断是否已经登录,如果没有登录就需要页面跳转到登录页,在这里我们需要进行判断请求是否为ajax请求,因为ajax请求无法直接进行页面的跳转,在这里我自己定义了一个Http转态代码,这样我前台可以根据转态代码准确的知道是否是后台出错,可以进行全局的捕获,如果不是ajax请求可以直接跳转Action;如果登录后因为本系统区分了前后台用户,在这里会直接把前台用户全部拦截,如果你的不区分可以去掉"
if(ui.iState == 1){....}
"这里面的代码;接下来我们获取controller,action和当前请求地址的绝对路径,然后去补全路径,最后获得全部路径判断是否在菜单路径中 参考注释 “ //判断请求页面或功能是否在菜单表中 在-》判断是否有权限 不在-》跳过 ”,如果需要判断权限则判断当前角色是否有该页面或功能的权限,没有权限就会返回提示
下面我们来看请求Action结束后的拦截代码
/// <summary>
/// 重写 在调用操作方法后调用 隐藏没有权限的按钮
/// </summary>
/// <param name="filterContext"></param>
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
string result = "";
//获取请求地址
string controllerName = (filterContext.RouteData.Values["controller"]).ToString().ToLower();
string actionName = (filterContext.RouteData.Values["action"]).ToString().ToLower();
string path = Request.Url.AbsolutePath.ToLower();
string pathLast = path.Split('/').Last();//判断是否没有输入全,由路由规则自动补全路径
if (path == "")
{
path = "/" + controllerName + "/" + actionName;
}
else if (pathLast == "")
{
path = path + controllerName + "/" + actionName;
}
else if (pathLast == controllerName)
{
path = path + "/" + actionName;
}
Menu m = SysCache.MenuList.Where(p => p.sHref.ToLower() == path).FirstOrDefault();//获取地址是否在菜单中
if (m != null)//判断请求地址是否在菜单列表中
{
//获取请求地址下的按钮集合
List<Menu> list = SysCache.MenuList.Where(p => p.gParentKey == m.gKey && p.iType == 3).ToList();
if (list.Count > 0)//表示请求地址下有需要权限的按钮存在
{
//获取角色权限菜单
List<RoleMenu> Rolelist = SysCache.RoleMenuList.Where(p => GetSessionUserInfo().sRoleKey.ToLower().Contains(p.gRoleKey.ToString())).ToList();
if (Rolelist.Count > 0)//表示角色有权限菜单
{
List<Guid> glist = Rolelist.Select(p => p.gMenuKey).ToList();
//获取按钮集合没有权限的菜单
var idList = list.Where(p => !glist.Contains(p.gKey)).Select(p => p.sBtnId);
result = string.Join(";", idList);
}
else
{
result = string.Join(";", list.Select(p => p.sBtnId));
}
}
}
//插入需要隐藏的按钮id
filterContext.Controller.ViewData["hideId"] = result;// "del;del1";
}
这个代码很简单,就是查询当前请求的Action页面是否有需要权限控制的按钮,有就把需要隐藏的按钮返回
然后我们看下前台js处理的代码
$(document).ready(function () {
var hideId = '@ViewData["hideId"]';//隐藏没有权限的按钮
var arr = hideId.split(";");
for (var i = 0; i < arr.length; i++) {
$("#" + arr[i]).css("display", "none");
}
})
很简单不需要解释
最后看下ajax处理http自定义转态码
//97表示系统内部错误 98表示没有登录 99表示没有权限
$.ajaxSetup({
statusCode: {
520: function (data) {
var data = $.parseJSON(data.responseText);
if (data.flag == "98") {
top.location.href = data.msg;
}
else {
if (getSpecialCode(data.msg)) {
alert(data.msg);
} else {
layui.use('layer', function () {
var layer = layui.layer;
parent.layer.open({
title: '提示',
content: data.msg,
icon: 2
});
})
}
}
}
}
})
这段代码单独的放到一个js文件,在布局页引用即可,我的全局拦截错误也使用的这个http转态码
不足:这种判断权限方法要求路由规则写的非常好,不能出现多个规则能定义到同一个页面
总结:以上是我个人对权限的判断,希望能对大家有所帮助
tip:联系方式 lhj0502@vip.qq.com 个人平时瞎写的网站: http://tangtu.top/ 账号test 密码test 欢迎体验