在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理。引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想,通过Filter能统一地对一些通用逻辑进行处理,如:权限校验、参数加解密、参数校验、日志记录、异常处理、性能测量等方面我们都可以利用这一特性进行统一处理,今天我们来介绍Filter的开发、使用以及讨论他们的执行顺序。
一、Filter的开发和调用在默认的WebApi中,框架提供了三种Filter,他们的功能和运行条件如下表所示:
Filter 类型
实现的接口
描述
Authorization
IAuthorizationFilter
最先运行的Filter,被用作请求权限校验
Action
IActionFilter
在Action运行的前、后运行
Exception
IExceptionFilter
当异常发生的时候运行
AuthorizatoinFilte
首先,我们实现一个AuthorizatoinFilter可以用以简单的权限控制(Basic Auth):
/// <summary> /// 权限控制 特性 /// </summary> public class AuthFilterAttribute : AuthorizationFilterAttribute { /// <summary> /// 在过程请求授权时调用。 /// </summary> /// <param></param> public override void OnAuthorization(HttpActionContext actionContext) { //如果用户方位的Action带有AllowAnonymousAttribute,则不进行授权验证 if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()) { return; } //要求请求中需要带有Authorization头,并且Authorization参数为123456则验证通过 if (actionContext.Request.Headers.Authorization != null) { string param = actionContext.Request.Headers.Authorization.Parameter; string schme = actionContext.Request.Headers.Authorization.Scheme.ToLower(); bool verifyResult = false; switch (schme) { //case AuthenticationSchemes.Basic.ToString(): case "basic": verifyResult = Validate(param); break; default: break; } if (!verifyResult) { //如果验证不通过,则返回401错误,并且Body中写入错误原因 actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, new HttpError("Token 不正确")); } } } /// <summary> /// Basic验证,每次请求API时都提供用户的username和password /// </summary> /// <param></param> /// <returns></returns> private bool Validate(string token) { bool result = false; byte[] c = Convert.FromBase64String(token); string baseString = System.Text.Encoding.Default.GetString(c); string[] up = baseString.Split(\':\'); if (up.Length >= 2) { result = up[0].ToLower() == "admin" && up[1].ToLower() == "123456"; } return result; } }