[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. jdk集合常用方法分析之HashSet和TreeSet

    HashSet常用方法介绍 public boolean add(E e) public boolean isEmpty() void clear() public Iterator<E> ...

  2. fw:理解RESTful架构

    理解RESTful架构   作者: 阮一峰 日期: 2011年9月12日 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立 ...

  3. 跨平台c++ Coroutine,仿unity3d实现

    不多说,贴代码: #include "stdafx.h" #include <list> #include <thread> #include <ch ...

  4. 【Unity Shaders】学习笔记——SurfaceShader(六)混合纹理

    [Unity Shaders]学习笔记——SurfaceShader(六)混合纹理 转载请注明出处:http://www.cnblogs.com/-867259206/p/5619810.html 写 ...

  5. python基础set

    1.set set是一个无序的不重复的集合 li=[11,22,33,11] s=set(li) print(s) {11,22,33}  set提供的方法 1.add(self, *args, ** ...

  6. 【测试】手工搭建DG

    前言:(一)准备工作: 1.数据库要处于归档模式: 2.监听参数:local_listener 默认值为空--1521 3.关闭闪回(可能会触发数据库的bug,备库不能开闪回) 4.如果有外部表,外部 ...

  7. $(function(){})与 (function(){})() (function($){})() 的区别

    1. $(function(){ }) 或 jQuery(function(){ }) 此函数也可以写成 jQuery(function(){ }), 用于存放操作DOM对象的代码,执行其中代码时DO ...

  8. django+celery+redis环境搭建

    初次尝试搭建django+celery+redis环境,记录下来,慢慢学习~ 1.安装apache 下载httpd-2.0.63.tar.gz,解压tar zxvf httpd-2.0.63.tar. ...

  9. dll延迟加载

    用于隐式链接选项, 这样设置后在exe调用dll的函数才会加载dll,调用DLL_PROCESS_ATTACH.否则隐式链接直接会在exe启动时加载dll

  10. python的文件操作方法

    python中的文件对象:文件对象不仅可以用来访问普通的磁盘文件, 而且也可以访问任何其它类型抽象层面上的"文件". 一旦设置了合适的"钩子", 你就可以访问具 ...