返回的IList就是系统中所有Action的集合,大家可看到我们通过BaseController找到了项目中所有的Controller,再通过ActionResult找到Controller中所有的Action。
不知道大家注意下拉出的Action有个描述属性,这个属性是通过在Action上定义DescriptionAttribute实现的,这样通过反射就能取到中文描述了,例如:为了实现页面的选取方便,我们还要实现对IList的分页和模糊查询,因为是变量级集合,这里我们使用Linq查询就可以了,代码如下:
[Description("访问功能权限管理页面")]
[ViewPage]
public ActionResult ActionPermission()
{
return View();
}
public IList<ActionPermission> QueryActionPlist(string query, int start, int limit, out long total)
{
IList<ActionPermission> allActions = GetAllActionByAssembly();
total = (from a in allActions
where a.ActionName.ToLower().Contains(query.ToLower())
select a).Count();
var result = (from a in allActions
where a.ActionName.ToLower().Contains(query.ToLower())
select a).Skip(start).Take(limit);
return new List<ActionPermission>(result);
}
[ViewPage]
public ActionResult ActionPermission()
{
return View();
}
public IList<ActionPermission> QueryActionPlist(string query, int start, int limit, out long total)
{
IList<ActionPermission> allActions = GetAllActionByAssembly();
total = (from a in allActions
where a.ActionName.ToLower().Contains(query.ToLower())
select a).Count();
var result = (from a in allActions
where a.ActionName.ToLower().Contains(query.ToLower())
select a).Skip(start).Take(limit);
return new List<ActionPermission>(result);
}
4.把权限判断相关的数据都缓存起来提高效率
我们把当前登录用户的:用户信息,拥有菜单权限,拥有功能权限 放在Session里
我们把需要托管的所有Action功能权限放在 Appliction全局应用程序变量里
这样我们所有的权限相关判断都是从缓存中取数据,不需要频繁访问数据了。
相关代码懒得贴了,自己去下载的源码里翻吧....注意一下缓存相关都是通过ICache这个接口出的,搜一下就能找到
5.如何对每个Action进行拦截,在它执行之前判断权限
最土的办法就是在每个Action加一段权限判断的代码,哈哈...如果我要这样做的话,估计要被大家的砖头拍死。
由于Asp.net MVC的Filter机制其实就是Aop,所以我们直接使用它。熟悉Asp.net MVC的朋友估计知道里面其实自带的有一个AuthorizeAttribute的ActionFilter,但基本就是个玩具,本来我想继承它重写的,但无奈里面的filterContext没有ActionDescriptor属性,所以干脆不要它自己写个ActionFilter,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using System.Security.Principal;
using Demo.HIS.Infrastructure.Facade.Authority;
namespace Demo.HIS.MVC.CommonSupport.Filter{
/// <summary>
/// 权限拦截
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class AuthorizeFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var path = filterContext.HttpContext.Request.Path.ToLower();
if (path == "/" || path == "/Main/Login".ToLower() || path == "/Main/UserLogin".ToLower())
return;//忽略对Login登录页的权限判定
object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(ViewPageAttribute), true);
var isViewPage = attrs.Length == 1;//当前Action请求是否为具体的功能页
if (this.AuthorizeCore(filterContext, isViewPage) == false)//根据验证判断进行处理
{
//注:如果未登录直接在URL输入功能权限地址提示不是很友好;如果登录后输入未维护的功能权限地址,那么也可以访问,这个可能会有安全问题
if (isViewPage == true)
{
filterContext.Result = new HttpUnauthorizedResult();//直接URL输入的页面地址跳转到登陆页
}
else
{
filterContext.Result = new ContentResult { Content = @"JsHelper.ShowError('抱歉,你不具有当前操作的权限!')" };//功能权限弹出提示框
}
}
}
//权限判断业务逻辑
protected virtual bool AuthorizeCore(ActionExecutingContext filterContext, bool isViewPage)
{
if (filterContext.HttpContext == null)
{
throw new ArgumentNullException("httpContext");
}
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
return false;//判定用户是否登录
}
var user = new CurrentUser();//获取当前用户信息
var controllerName = filterContext.RouteData.Values["controller"].ToString();
var actionName = filterContext.RouteData.Values["action"].ToString();
if (isViewPage && (controllerName.ToLower() != "main" && actionName.ToLower() != "masterpage"))//如果当前Action请求为具体的功能页并且不是MasterPage页
{
if (user.MenuPermission.Count(m => m.ControllerName == controllerName && m.ActionName == actionName) == 0)
return false;
}
else
{
var actions = ContainerFactory.GetContainer().Resolve<IAuthorityFacade>().GetAllActionPermission();//所有被维护的Action权限
if (actions.Count(a => a.ControllerName == controllerName && a.ActionName == actionName) != 0)//如果当前Action属于被维护的Action权限
{
if (user.ActionPermission.Count(a => a.ControllerName == controllerName && a.ActionName == actionName) == 0)
return false;
}
}
return true;
}
}}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using System.Security.Principal;
using Demo.HIS.Infrastructure.Facade.Authority;
namespace Demo.HIS.MVC.CommonSupport.Filter{
/// <summary>
/// 权限拦截
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class AuthorizeFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var path = filterContext.HttpContext.Request.Path.ToLower();
if (path == "/" || path == "/Main/Login".ToLower() || path == "/Main/UserLogin".ToLower())
return;//忽略对Login登录页的权限判定
object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(ViewPageAttribute), true);
var isViewPage = attrs.Length == 1;//当前Action请求是否为具体的功能页
if (this.AuthorizeCore(filterContext, isViewPage) == false)//根据验证判断进行处理
{
//注:如果未登录直接在URL输入功能权限地址提示不是很友好;如果登录后输入未维护的功能权限地址,那么也可以访问,这个可能会有安全问题
if (isViewPage == true)
{
filterContext.Result = new HttpUnauthorizedResult();//直接URL输入的页面地址跳转到登陆页
}
else
{
filterContext.Result = new ContentResult { Content = @"JsHelper.ShowError('抱歉,你不具有当前操作的权限!')" };//功能权限弹出提示框
}
}
}
//权限判断业务逻辑
protected virtual bool AuthorizeCore(ActionExecutingContext filterContext, bool isViewPage)
{
if (filterContext.HttpContext == null)
{
throw new ArgumentNullException("httpContext");
}
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
return false;//判定用户是否登录
}
var user = new CurrentUser();//获取当前用户信息
var controllerName = filterContext.RouteData.Values["controller"].ToString();
var actionName = filterContext.RouteData.Values["action"].ToString();
if (isViewPage && (controllerName.ToLower() != "main" && actionName.ToLower() != "masterpage"))//如果当前Action请求为具体的功能页并且不是MasterPage页
{
if (user.MenuPermission.Count(m => m.ControllerName == controllerName && m.ActionName == actionName) == 0)
return false;
}
else
{
var actions = ContainerFactory.GetContainer().Resolve<IAuthorityFacade>().GetAllActionPermission();//所有被维护的Action权限
if (actions.Count(a => a.ControllerName == controllerName && a.ActionName == actionName) != 0)//如果当前Action属于被维护的Action权限
{
if (user.ActionPermission.Count(a => a.ControllerName == controllerName && a.ActionName == actionName) == 0)
return false;
}
}
return true;
}
}}