系列导航
Q78. 介绍下 ASP.NET MVC 中的 Filters(过滤器) 和 Attributes(特性)?
Ans. ASP.NET MVC 提供了一种简单的方式在 action 执行之前或之后注入一段代码或逻辑,它就是 ASP.NET MVC attributes,通过在 Controller 或者 Action 上使用 Attributes 来修饰即可。可以自定义过滤器或特性通过实现 ASP.NET
MVC filter 接口或继承并重载 ASP.NET MVC filter attribute 类。
通常,过滤器被用来执行以下常见的功能点:
Q79. 介绍下 ASP.NET MVC 中几种不同的 Filters(过滤器) ?
Ans. 主要有以下五种类型 Filters:
Authentication Filters(认证过滤器)
该过滤器是从 ASP.NET MVC5 中引入的。
接口是用来创建自定义认证过滤器。
- IAuthenticationFilter
定义如下:
- IAuthenticationFilter
- public interface IAuthenticationFilter
- {
- void OnAuthentication(AuthenticationContext filterContext);
- void OnAuthenticationChallenge(AuthenticationChallengeContext
- filterContext);
- }
通过实现
接口,即可实现自定义的认证过滤特性。
- IAuthenticationFilter
- public class CustomAuthenticationFilterAttribute : FilterAttribute,
- IAuthenticationFilter
- {
- public void OnAuthentication(AuthenticationContext filterContext)
- {
- filterContext.HttpContext.Response.Write("Authentication
- Filter<br/>");
- }
- //Runs after the OnAuthentication method
- public void OnAuthenticationChallenge(AuthenticationChallengeContext
- filterContext)
- {
- //TODO: Additional tasks on the request
- }
- }
Authorization Filters(授权过滤器) - ASP.NET MVC 的授权过滤器实现了
接口。
- IAuthorizationFilter
- public interface IAuthorizationFilter
- {
- void OnAuthorization(AuthorizationContext filterContext);
- }
提供了以下可重载的方法:
- AuthorizeAttribute
- public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
- {
- protected virtual bool AuthorizeCore(HttpContextBase httpContext);
- protected virtual void HandleUnauthorizedRequest(AuthorizationContext
- filterContext);
- public virtual void OnAuthorization(AuthorizationContext filterContext);
- protected virtual HttpValidationStatus
- OnCacheAuthorization(HttpContextBase httpContext);
- }
所以,我们可以通过实现
接口或者继承
- IAuthorizationFilter
类然后重载虚方法来创建自定义的授权过滤器。
- AuthorizeAttribute
Action Filters(操作过滤器)
Action filters 在 action 执行之前和之后执行。
接口提供了
- IActionFilter
和
- OnActionExecuting
方法分别对应 action 之前和 action 之后执行。
- OnActionExecuted
- public interface IActionFilter
- {
- void OnActionExecuting(ActionExecutingContext filterContext);
- void OnActionExecuted(ActionExecutedContext filterContext);
- }
Result Filters(结果过滤器)
Result filters 在为 action 生成结果之前和和之后执行。返回的结果可以是 ViewResult、PartialViewResult、RedirectToRouteResult、RedirectResult、ContentResult、JsonResult、FileResult 和 EmptyResult ,它们均继承自 ActionResult 类。Result filters 在 Action Filters 之后调用。
接口提供了
- IResultFilter
和
- OnResultExecuting
方法分别对应生成结果之前和之后执行。
- OnResultExecuted
- public interface IResultFilter
- {
- void OnResultExecuted(ResultExecutedContext filterContext);
- void OnResultExecuting(ResultExecutingContext filterContext);
- }
Exception Filters(异常过滤器) - Exception filters 在 action 或者过滤器执行期间出现异常时执行。
接口提供了
- IExceptionFilter
方法来处理异常。
- OnException
- public interface IExceptionFilter
- {
- void OnException(ExceptionContext filterContext);
- }
类实现了
- HandleErrorAttribute
接口。 当
- IExceptionFilter
接收到异常,它会直接返回 ASP.NET MVC Views/Shared 文件夹下的
- HandleError
视图。
- Error
Q80. ASP.NET MVC 的 Exception filters(异常过滤)何时执行?
Ans. Exception filters 在 ASP.NET MVC pipeline(管道)执行期间有一个未处理的异常抛出时被执行。
Q81. ASP.NET MVC 中 filters(过滤器)的执行顺序是?
Ans. 所有的 ASP.NET MVC filter 都是按照一定的顺序执行。 执行顺序为:
Q82. ASP.NET MVC 中如何配置过滤器?
Ans. 我们可以配置自定义的过滤器为以下三个级别:
Global level(全局级别)
将过滤器注册到
文件的
- Global.asax.cs
方法中:
- Application_Start
- protected void Application_Start()
- { FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- }
Controller level(控制器级别)
通过将过滤器标记在 controller 上即可。
- [Authorize(Roles = "Admin")]
- public class AdminController : Controller
- {
- //TODO:
- }
Action level (操作级别)
通过将过滤器标记在 action 上即可。
- public class UserController : Controller
- {
- [Authorize(Users = "User1,User2")]
- public ActionResult LinkLogin(string provider)
- {
- // TODO:
- return View();
- }
- }
Q83. ASP.NET MVC 中认证和授权是如何工作的?
Ans. 像 ASP.NET 一样,MVC 也支持 Windows 和 Forms 认证。可以通过在 web.config 中配置或自己编码。
Q84. ASP.NET MVC 中 Forms Authentication 和 Authorization(表单认证和授权)是如何工作的?
Ans. 和 ASP.NET 一样, MVC Forms authentication 在 IIS 认证完成之后发生。可以在 ASP.NET MVC 应用程序中的 Web.config 文件的 forms 节点进行配置。
默认的表单认证配置如下:
- <system.web>
- <authentication mode="Forms">
- <forms loginUrl="Login.aspx"
- protection="All"
- timeout="30"
- name=".ASPXAUTH"
- path="/"
- requireSSL="false"
- slidingExpiration="true"
- defaultUrl="default.aspx"
- cookieless="UseDeviceProfile"
- enableCrossAppRedirects="false" />
- </authentication>
- </system.web>
当
或
- SetAuthCookie()
被调用时
- RedirectFromLoginPage()
类自动创建认证 Cookie。 Authentication cookie(认证 Cookie)中包含一个已经加密和签名的
- FormsAuthentication
对象的字符串。 可以指定 cookie 的名称、 版本、目录路径、生效日期、过期日期、是否永久属性来创建
- FormsAuthenticationTicket
对象 。
- FormsAuthenticationTicket
- FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "userName",
- DateTime.Now,
- DateTime.Now.AddMinutes(30), // value of time out property
- false, // Value of IsPersistent property
- String.Empty, FormsAuthentication.FormsCookiePath);
然后就可以使用
类的
- FormsAuthentication
方法来加密 ticket。
- Encrypt
- string encryptedTicket = FormsAuthentication.Encrypt(ticket);
Q85. ASP.NET MVC 中如何实现自定义 Forms Authentication and Authorization(表单认证和授权)?
Ans. 当标准的认证不能满足你的需求,你就需要去修改认证机制去创建自定义的认证方案。一个用户上下文有一个 Principal,这个 Principal 代表用户的身份(Identity)和角色(Role)。用户通过 ta 的身份进行认证,通过给用户分配角色来进行授权。
ASP.NET 提供了
和
- IPrincipal
接口来表示用户的身份和角色。这两个接口
- IIdentity
- public class CustomPrincipal: IPrincipal {
- public IIdentity Identity {
- get;
- private set;
- }
- public bool IsInRole(string role) {
- if (roles.Any(r = >role.Contains(r))) {
- return true;
- } else {
- return false;
- }
- }
- public CustomPrincipal(string Username) {
- this.Identity = new GenericIdentity(Username);
- }
- public int UserId {
- get;
- set;
- }
- public string FirstName {
- get;
- set;
- }
- public string LastName {
- get;
- set;
- }
- public string[] roles {
- get;
- set;
- }
- }
现在你就可以把
对象放入 thread(线程)的
- CustomPrincipal
属性和 HttpContext 的
- CurrentPrincipal
属性来完成自定义的认证和授权流程。 如果
- User
返回 true 则表示用户认证成功。我们可以用以下两种方式来完成对用户的验证。
- IsAuthenticated
ASP.NET MVC 提供了
授权过滤器来对用户授权。该过滤器可适用于 action 级别、控制器级别和全局级别。该过滤器基于
- Authorization
特性类,可以通过继承该特性并重载
- AuthorizeAttribute
方法来对授权过滤器进行自定义。
- OnAuthorization()
- public class CustomAuthorizeAttribute: AuthorizeAttribute {
- protected virtual CustomPrincipal CurrentUser {
- get {
- return HttpContext.Current.User as CustomPrincipal;
- }
- }
- public override void OnAuthorization(AuthorizationContext filterContext) {
- if (filterContext.HttpContext.Request.IsAuthenticated) {
- if (!String.IsNullOrEmpty(Roles)) {
- if (!CurrentUser.IsInRole(Roles)) {
- filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
- controller = "Error",
- action = "AccessDenied"
- }));
- }
- }
- if (!String.IsNullOrEmpty(Users)) {
- if (!Users.Contains(CurrentUser.UserId.ToString())) {
- filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
- controller = "Error",
- action = "AccessDenied"
- }));
- // base.OnAuthorization(filterContext); //returns to login url
- }
- }
- }
- }
- }
现在你就可以像下面这样应用自定义的授权过滤器在控制器级别或者 action 级别。
- [CustomAuthorize(Roles= "Admin")]
- public class AdminController : BaseController
- {
- public ActionResult Index()
- {
- return View();
- }
- }
来源: http://www.cnblogs.com/sheng-jie/p/6427239.html