Asp.net MVC中的全局权限验证方法及实现
2012-02-22 14:32
666 查看
开发过MVC的人都知道,MVC是三个单词的缩写,分别为: 模型(Model),视图(View)和控制Controller)。 MVC模式的目的就是实现Web系统的职能分工。 Model层实现系统中的业务逻辑。 View层用于与用户的交互。 Controller层是Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。
我们的权限验证就添加在控制(Controller)层,这是必然的。验证的机制就是,每一次客户端对于Controller里边的Action的请求之前,都会先验证用户的身份,也就是说,用户每一次对于数据的请求,都会验证当前用户是否有使用该数据的权限。
本文所介绍的MVC身份验证大致分为以下四个部分:
AuthenticationAsserts 授权验证的相关断言
AuthorizationFilter 验证过滤器的构造函数
ControllerActionInvoker 自定义ControllerActionInvoker
DefaultControllerFactory 自定义的ControllerFactory,可以通过ControllerFactory向Controller中植入相关的ActionInvoker
下边先从授权验证的相关断言说起,验证断言的作用是:确定用户的请求是否需要验证和确认是否以验证过。它主要包含以下几个方法:精确的权验验证,确定系统是否需要验证,确定用户是否已经通过验证,以及判断用户是否拥有访问该URL的权限。下边看看代码:
然后就该是过滤器部分了:
然后就该说说自定义ControllerActionInvoker了。也就是ControllerAction的回调函数:
最后该说说我们的工厂类了:
自定义的ControllerFactory,可以通过ControllerFactory向Controller中植入相关的ActionInvoker
到这里就把全部的代码写在上边了。
在使用的时候,只需在Global.asax里边的Application_Start()里边写入我们在路由里边对于我们的方法的注册就好了:
到这个时候,我们在Controller里边就不需要打标签了,默认的就是所有的Action都会进行我们提前设计好的权限验证了。
到这里就结束了,时间关系,没有讲的很细,不明白的就看代码吧。
我们的权限验证就添加在控制(Controller)层,这是必然的。验证的机制就是,每一次客户端对于Controller里边的Action的请求之前,都会先验证用户的身份,也就是说,用户每一次对于数据的请求,都会验证当前用户是否有使用该数据的权限。
本文所介绍的MVC身份验证大致分为以下四个部分:
AuthenticationAsserts 授权验证的相关断言
AuthorizationFilter 验证过滤器的构造函数
ControllerActionInvoker 自定义ControllerActionInvoker
DefaultControllerFactory 自定义的ControllerFactory,可以通过ControllerFactory向Controller中植入相关的ActionInvoker
下边先从授权验证的相关断言说起,验证断言的作用是:确定用户的请求是否需要验证和确认是否以验证过。它主要包含以下几个方法:精确的权验验证,确定系统是否需要验证,确定用户是否已经通过验证,以及判断用户是否拥有访问该URL的权限。下边看看代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using Configuration; using Membership; using System.Web; using User.ServiceImp; using MVCExtension; namespace Authorization { /// <summary> /// 授权验证的相关断言。 /// </summary> public class AuthenticationAsserts { /// <summary> /// 确认系统是否需要权限验证(系统在开发期间,为了开发调试方便,可以不需要权限验证,而在开发完成后,套用框架后才要求验证)。 /// </summary> /// <returns>如果需要验证,则返回True,否则返回False</returns> public static bool IsRequireAuthenticate() { try { return bool.Parse(ConfigConstString.Instance.IsSOAVlidate); } catch { return false; } } /// <summary> /// 判断用户是否已经通过登录验证 /// </summary> /// <param name="controllerContext">Controller的上下文</param> /// <returns>如果通过验证,返回True,否则返回False</returns> public static bool IsAuthenticated(ControllerContext controllerContext) { return controllerContext.HttpContext.User.Identity.IsAuthenticated; } /// <summary> /// 判断Action是否标示为避免验证?(AvoidAuthenticateAttribute) /// </summary> /// <returns>如果该Action标示为避免验证,返回True,否则返回False。</returns> public static bool IsActionAvoidAuthenticate(ControllerContext Controller, IList<IAuthorizationFilter> filters) { bool _ISSecure =false; foreach (IAuthorizationFilter filer in filters) { if (filer is SecureFilterAttribute) { SecureFilterAttribute secureFilterAttribute = (SecureFilterAttribute)filer; _ISSecure = (bool)secureFilterAttribute.ISSecure; if (_ISSecure) break; } else if (filer is ElinkFilterAttribute) { string controller = Controller.Controller.ToString(); string id = HttpContext.Current.Request.Params["ElinkID"]; try { Guid linkid = id == null ? Guid.NewGuid() : new Guid(id); _ISSecure =UserGateway.TenantProvider.IsLinkerSecure(controller, linkid,""); } catch(Exception e) { _ISSecure = false; } break; } else if(filer is AccurateFilterAttribute)//链接授权 { Identity bi = (Identity)Controller.HttpContext.User.Identity; int userid = bi.UserID; HttpRequest httpRequest = new HttpRequest(string.Empty, Controller.HttpContext.Request.Url.ToString(), Controller.HttpContext.Request.QueryString.ToString()); bool result = UserGateway.TenantSecurityProvider.IsSignatureUrlsecure(httpRequest,userid); _ISSecure = result; } } return _ISSecure; } /// <summary> /// 精确授权验证 /// </summary> /// <param name="Controller"></param> /// <param name="filters"></param> /// <returns></returns> public static bool IsAccurateAuthenticate(ControllerContext Controller, IList<IAuthorizationFilter> filters) { bool _ISSecure = true; foreach (IAuthorizationFilter filer in filters) { if (filer is AccurateFilterAttribute)//链接授权 { Identity bi = (Identity)Controller.HttpContext.User.Identity; int userid = bi.UserID; HttpRequest httpRequest = new HttpRequest(string.Empty, Controller.HttpContext.Request.Url.ToString(), Controller.HttpContext.Request.QueryString.ToString()); bool result = UserGateway.TenantSecurityProvider.IsSignatureUrlsecure(httpRequest, userid); _ISSecure = result; } } return _ISSecure; } /// <summary> /// 判断用户是否拥有访问该URL的权限。 /// 用户是否授权访问该URL包括两个部分: ///1.用户有该URL对应功能的访问角色; ///2.用户所在租户拥有该功能的使用授权。 /// </summary> /// <param name="url">当前访问的URL</param> /// <returns>如果用户有权访问该URL,返回true,否则返回False。</returns> public static bool IsUserHasPermissionAccess(Type controllerType, string actionName) { string url=HttpContextGateWay.Instance.GetHttpContext().Request.Url.AbsolutePath; bool result = MembershipProviderGateWay.Instance.IsFuntionUsableByUrl(url);//||MembershipProviderGateWay.Instance.IsFuntionUsableByUrl(fullActionUrl) return result; } } }
然后就该是过滤器部分了:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; using System.Web.Mvc; using System.Web.Security; using BI.Common.Model; using User.ServiceImp; using Membership; namespace Authorization { partial class BIAuthorizationFilter : IAuthorizationFilter { private Type _controllerType; private string _actionName; private readonly ControllerContext _controllerContext; private readonly IList<IAuthorizationFilter> _filters; /// <summary> /// 自定义验证过滤器的构造函数 /// </summary> /// <param name="controllerType">当前的controllerType</param> /// <param name="actionName">当前调用的actionName</param> public BIAuthorizationFilter(IList<IAuthorizationFilter> filters, Type controllerType, string actionName, ControllerContext controllerContext) { _controllerType = controllerType; _actionName = actionName; _controllerContext = controllerContext; _filters = filters; } public void OnAuthorization(AuthorizationContext filterContext) { //权限验证部分代码 } /// <summary> /// 得到完整Url /// </summary> /// <returns></returns> public string GetCurrentFullUrl(AuthorizationContext context) { return string.Format("{0}://{1}{2}", context.HttpContext.Request.Url.Scheme, context.HttpContext.Request.Url.Host, c ontext.HttpContext.Request.RawUrl); } private void RedirectToLogin(AuthorizationContext context, string url) { context.HttpContext.Response.Redirect(String.Format("{0}?ReturnUrl={1}", FormsAuthentication.LoginUrl, HttpUtility.U rlEncode(url))); } } }
然后就该说说自定义ControllerActionInvoker了。也就是ControllerAction的回调函数:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using BI.Authorization; namespace BI.Authorization { /// <summary> /// 自定义ControllerActionInvoker /// </summary> public class BIControllerActionInvoker:ControllerActionInvoker { protected override AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor) { //在这里插入自定义的验证Filter if(filters == null) { filters = new List<IAuthorizationFilter>(); } IAuthorizationFilter filter = new BIAuthorizationFilter(filters, actionDescriptor.ControllerDescriptor.ControllerType, actionDescriptor.ActionName, controllerContext); filters.Insert(0,filter); return base.InvokeAuthorizationFilters(controllerContext, filters, actionDescriptor); } } }
最后该说说我们的工厂类了:
自定义的ControllerFactory,可以通过ControllerFactory向Controller中植入相关的ActionInvoker
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; namespace BI.Authorization { /// <summary> /// 自定义的ControllerFactory,可以通过ControllerFactory向Controller中植入相关的ActionInvoker /// </summary> public class BIDefaultControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { requestContext.HttpContext.Response.BufferOutput = true; IController instance = base.GetControllerInstance(requestContext, controllerType); if (instance != null && typeof(Controller).IsAssignableFrom(controllerType)) { Controller controller = (Controller)instance; //依赖注入 controller.ActionInvoker = new BIControllerActionInvoker(); //controller. return controller; } else { return instance; } } } }
到这里就把全部的代码写在上边了。
在使用的时候,只需在Global.asax里边的Application_Start()里边写入我们在路由里边对于我们的方法的注册就好了:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ControllerBuilder.Current.SetControllerFactory(new BIDefaultControllerFactory()); RegisterRoutes(RouteTable.Routes); }
到这个时候,我们在Controller里边就不需要打标签了,默认的就是所有的Action都会进行我们提前设计好的权限验证了。
public ActionResult Index() { ViewData["ReportName"] = "绩效考核进程报表"; ViewData["EncryptionString"] = str; return View(); }
到这里就结束了,时间关系,没有讲的很细,不明白的就看代码吧。
相关文章推荐
- Asp.net MVC 权限过滤器实现方法的最佳实践
- asp.net继承page类重写方法 实现最基本的用户登录验证 权限验证等
- asp.net mvc 控制器&动作方法 角色 权限验证
- ASP.NET MVC(模型(Model),视图(View)和控制Controller)实践:实现身份验证权限管理
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
- asp.net继承page类重写方法 实现最基本的用户登录验证 权限验证等
- ASP.NET MVC使用ActionFilterAttribute实现权限限制的方法(附demo源码下载)
- asp.net mvc 全局权限过滤器及继成权限方法
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
- asp.net mvc 全局权限过滤器及继成权限方法
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证)
- ASP.NET MVC 中实现基于角色的权限控制的处理方法
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
- ASP.NET MVC 中实现基于角色的权限控制的处理方法
- ASP.NET MVC中对Model进行分步验证的解决方法
- 使用 ExtJS 实现 ASP.NET MVC 2 客户端验证
- ASP.NET MVC 实现全局 页面重定向
- asp.net获取当前页面文件名,参数,域名等方法。统一session验证和权限验证的方法