Web Api 过滤器之 AuthorizationFilter 验证过滤器
该过滤器是最先执行的过滤器,即使把它放在最后
API
[MyActionFilter] [MyExceptionFilter] [MyAuthorize] public void Get() { Trace.WriteLine("还有谁!!!"); } public class MyActionFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { Trace.WriteLine("我是 Action 过滤器 OnActionExecuting 方法"); } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { Trace.WriteLine("我是 Action 过滤器 OnActionExecuted 方法"); } } public class MyAuthorizeAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) { Trace.WriteLine("我是 Authorization 过滤器");var headers = actionContext.Request.Headers; var authorization = headers.Authorization; var validateResult = authorization != null && authorization.Scheme.Equals("mima")&&authorization.Parameter.Equals("123456"); if (!validateResult) { //actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized) //{ // Content = new StringContent("授权未通过") //}; //从方法名来看,感觉这种写法比上面注释掉的要符合规范一点 actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "授权未通过"); } } }
客户端调用:
static void Main(string[] args) {
using (var client = HttpClient()) { client.BaseAddress = new Uri("http://localhost:58254"); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("mima","123456789"); client.GetAsync("api/test/get").ContinueWith(GetResponse); Console.WriteLine("这是主线程,我最先被显示出来"); Console.ReadKey();
} } private static void GetResponse(Task<HttpResponseMessage> obj) { var getResult = obj.Result; var str = getResult.IsSuccessStatusCode ? "请求成功!" : "请求失败"; Console.WriteLine(str); var readResult = getResult.Content.ReadAsStringAsync(); Console.WriteLine(readResult.Result); }
运行结果:
权限验证基本上每个API都一样,所以都是注册的全局:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服务 //跨域 EnableCrossSiteRequests(config); //注册过滤器 config.Filters.Add(new MyAuthorizeAttribute()); ......
如果想让某些API不进行验证,比如登录等,则可以进行如下处理:
1.再不需要验证的 Controller 或者 Action 上面打上 [AllowAnonymous]
[RoutePrefix("api/test")] public class TestController : ApiController { [MyActionFilter] [MyExceptionFilter] [MyAuthorize] [AllowAnonymous] public void Get() { Trace.WriteLine("还有谁!!!"); }
2.
public class MyAuthorizeAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) { Trace.WriteLine("我是 Authorization 过滤器"); //检查当前请求的 Action 是否有[AllowAnonymous],有的话则直接返回,不再进行下面的验证 if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()) { return; } //检查当前请求的 Controller 是否有[AllowAnonymous],有的话则直接返回,不再进行下面的验证 if (actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()) { return; }