[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class PowerAttribute : FilterAttribute, IActionFilter
{ public void OnActionExecuted(ActionExecutedContext filterContext)
{
//throw new NotImplementedException();
}
/// <summary>
/// 权限标示名
/// </summary>
public string PowerName { get; set; }
/// <summary>
/// 是否超级管理员应用
/// </summary>
public bool IsSuper = false; protected User LoginUser = null; protected PowerConfig Power = null; public IPowerConfigService powerConfigService = AutofacDependencyResolver.Current.ApplicationContainer.Resolve<IPowerConfigService>(); public void OnActionExecuting(ActionExecutingContext filterContext)
{
LoginUser = CacheHelper.GetCache(Constant.CacheKey.LoginUserInfoCacheKey + "_" + filterContext.HttpContext.User.Identity.Name) as User;
bool b = false; if (IsSuper == false)
{
//非超级管理员专属操作 //权限id集合
string[] acts = LoginUser.Role.ActionIds.Split(','); Power = CacheHelper.GetCache(Constant.CacheKey.PowerConfigCacheKey) as PowerConfig; if (Power == null)
{
Power = powerConfigService.LoadConfig(Constant.PowerConfigPath);
CacheHelper.SetCache(Constant.CacheKey.PowerConfigCacheKey, Power);
} try
{
if (Power != null)
{
var p = Power.PowerList.FirstOrDefault(t => t.Name == PowerName);
if (p != null)
{
if (acts.Contains(p.Id.ToString()))
{
//存在权限
b = true;
}
}
}
}
catch
{
b = false;
}
}
//超级管理员都可以使用
if (LoginUser.IsSuperUser)
{
b = true;
} #region 无权限执行
if (b == false)
{ //无权限执行
if (filterContext.HttpContext.Request.IsAjaxRequest())
{ //filterContext.Result = new JsonResult() {
// Data = new { pass = false, error = "无权访问" },
// JsonRequestBehavior=JsonRequestBehavior.AllowGet
//}; filterContext.Result = new ContentResult()
{
Content = "无权访问",
ContentEncoding = Encoding.UTF8
};
}
else
{
filterContext.Controller.ViewData["ErrorMessage"] = "无权访问";//filterContext.Exception.Message + " 亲!您犯错了哦!";//得到报错的内容
filterContext.Result = new ViewResult()//new一个url为Error视图
{
ViewName = "Error",/*在Shard文件夹下*/
ViewData = filterContext.Controller.ViewData//view视图的属性中的viewdata被赋值
};
}
}
#endregion
}
}

使用这个过滤拦截各种action的访问,做到权限的颗粒化,使用时候直接在action或者controller的头部加[Power(IsSuper=true,PowerName="权限名")],IsSuper是针对系统超级管理员设计,判断action是否为系统级别的action,一般是配置或者高权限的action使用,普通可以不写,或者为false。

power的参数配置我放到了两个地方,一个数据库,另一个是config文件,数据库可以通过我设计的导出,直接变成config。在运行时候根据角色的actionId去配置文件中取出ID对应的powername,然后根据powename进行判断(powername可以重复,有利于action的细化分组)

<?xml version="1.0"?>
<PowerConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PowerGroupList>
<PowerGroup>
<GroupName>操作组一</GroupName>
<Id>1</Id>
</PowerGroup>
<PowerGroup>
<GroupName>操作组二</GroupName>
<Id>2</Id>
</PowerGroup>
</PowerGroupList>
<PowerList>
<Power>
<ParamStr>/cms/1234</ParamStr>
<Name>统计</Name>
<GroupId>1</GroupId>
<Id>2</Id>
</Power>
<Power>
<ParamStr>/cms/12345</ParamStr>
<Name>介绍</Name>
<GroupId>1</GroupId>
<Id>3</Id>
</Power>
<Power>
<ParamStr>/links/123</ParamStr>
<Name>友情链接</Name>
<GroupId>1</GroupId>
<Id>7</Id>
</Power>
<Power>
<ParamStr>/cms/123</ParamStr>
<Name>合作单位</Name>
<GroupId>1</GroupId>
<Id>8</Id>
</Power>
<Power>
<ParamStr>/proj</ParamStr>
<Name>产品展示</Name>
<GroupId>1</GroupId>
<Id>9</Id>
</Power>
<Power>
<ParamStr>/message</ParamStr>
<Name>客户留言</Name>
<GroupId>1</GroupId>
<Id>10</Id>
</Power>
<Power>
<ParamStr>/gundong</ParamStr>
<Name>滚动图</Name>
<GroupId>1</GroupId>
<Id>11</Id>
</Power>
<Power>
<ParamStr>/guangao</ParamStr>
<Name>广告位</Name>
<GroupId>1</GroupId>
<Id>12</Id>
</Power>
<Power>
<ParamStr>/cms/123</ParamStr>
<Name>文章</Name>
<GroupId>2</GroupId>
<Id>1</Id>
</Power>
<Power>
<ParamStr>/admin/ActionAdd</ParamStr>
<Name>文章查看</Name>
<GroupId>2</GroupId>
<Id>4</Id>
</Power>
<Power>
<ParamStr>/cms/12</ParamStr>
<Name>文章删除</Name>
<GroupId>2</GroupId>
<Id>5</Id>
</Power>
<Power>
<ParamStr>/cms/123</ParamStr>
<Name>文章修改</Name>
<GroupId>2</GroupId>
<Id>6</Id>
</Power>
</PowerList>
</PowerConfig>

上面就是生成的config,运行时候会加载到缓存,提高性能。他的生成是基于,Action和ActionGroup的,而Action和ActionGroup数据会存储到数据库,可以可视化添加。

在EF的code frist下写稳健的权限管理系统:MVC过滤拦截,权限核心(五)的更多相关文章

  1. 在EF的code frist下写稳健的权限管理系统:数据库模型(二)

    先从数据库开始,因为是用EF的code frist,所以所有的设计都在解决项目中进行. 先是数据模型开始 我已经建立了四个模型,user,role,action,actiongroup user里面有 ...

  2. 在EF的code frist下写稳健的权限管理系统:界面设计(四)

    基本都是采用pure设计(中文官网:http://purecss.org,英文官网:http://purecss.io).pure只是一个简单强大的cssUI库,支持响应式设计,适合自己设计或者给美工 ...

  3. 在EF的code frist下写稳健的权限管理系统:仓储设计(三)

    public class BaseRepository<T>:IBaseRepository<T> where T : class { protected EfConnecti ...

  4. 在EF的code frist下写稳健的权限管理系统:开篇(一)

    环境:EF6.0.0.0+Autofac3.5.0.0+MVC4.0+pure6.0+Jquery IDE:vs2012,数据库:vs2008r2 搭建环境如下: 我给它取名字为cactus:仙人球, ...

  5. ef core code frist

    https://docs.microsoft.com/zh-cn/ef/core/get-started/aspnetcore/new-db?view=aspnetcore-2.1 1.先创建对应的实 ...

  6. 从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑

    前言      从上篇30岁找份程序员的工作(伪程序员的独白),文章开始,我说过我要用我自学的技术,来搭建一个博客系统,也希望大家给点意见,另外我很感谢博客园的各位朋友们,对我那篇算是自我阶段总结文章 ...

  7. 【干货】利用MVC5+EF6搭建博客系统(一)EF Code frist、实现泛型数据仓储以及业务逻辑

    习MVC有一段时间了,决定自己写一套Demo了,写完源码再共享. PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.框架搭建 二.创建数据库 1.创建一个空的EF code fr ...

  8. 8天掌握EF的Code First开发系列之动手写第一个Code First应用

    返回<8天掌握EF的Code First开发>总目录 本篇目录 创建控制台项目 根据.Net中的类来创建数据库 简单的CRUD操作 数据库模式更改介绍 本章小结 自我测试 上一篇<8 ...

  9. 使用 EF Power Tool Code Frist 生成 Mysql 实体

    原文:使用 EF Power Tool Code Frist 生成 Mysql 实体 1,在要生成的项目上右键   2,   3,   4,   5,  生成后的效果     已知问题: 1,在Mys ...

随机推荐

  1. phpmyadmin #2003 无法登录 MySQL服务器的解决方法

    本文章向大家介绍phpmyadmin #2003 无法登录 MySQL服务器的解决方法,需要的码农可以参考一下. 通过phpmyadmin连接mysql数据库时提示:"2003 无法登录 M ...

  2. WebsitePanel 2.1.0beta配置部分

    到http://www.websitepanel.net/downloads/下载好单独安装包作为网站内容运行在IIS7.0上,配置applicationpool为localsystem Websit ...

  3. VS error retrieving information from user datastore

    搭建好VS2005+PB6.0的开发环境后,新建MFC智能设备应用程序工程出错,错误信息如下: error retrieving information from user datastore 很奇怪 ...

  4. oracle错误处理及实操-【INS-20802】

    服务器硬件要求:内存>1GB,如果是虚拟机,必须设置内存为1.5G以上. 确定好主机名,安装完成以后,不要再修改主机名,一旦修改会导致oracle启动失败,注意:使用默认的localhost.l ...

  5. Redis主从是否生效的特殊测试方法

    Redis主从的特殊测试方法 配置主从 Redis的主从设定,相较于MySQL的主从,配置起来非常简单,不必像MySQL数据库一样手动记录bin log的位置再配置,但又可以像MySQL一样,一主带多 ...

  6. python其中一个子线程,则退出全部线程,再退出进程

    import threading, signal is_exit = False def write_login(self): global is_exit write_log('login rsyn ...

  7. 学习记录 java 值类型和引用类型的知识

    1. Java中值类型和引用类型的不同? [定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变 ...

  8. Linq to XML---网站地图和RSS Feed(ASP.NET的SEO)

    本系列目录网站地图的作用是让搜索引擎尽快的,更多的收录网站的各个网页.    这里我们首先要明白一个基本的原理,搜索引擎的爬行方式.整个互联网就像一张纵横交错的"网":网的各个节点 ...

  9. Oracle笔记 十、PL/SQL存储过程

    --create or replace 创建或替换,如果存在就替换,不存在就创建 create or replace procedure p is cursor c is select * from ...

  10. Atom markdown .md 编写格式技巧

    使用Atom预览markdown 1.打开任意.md文件(markdown源文件) 菜单栏File->Open file...(ctrl+o)打开文件: 2.windows下使用快捷键 ctrl ...