使Web API身份validation返回401而不是重定向到登录页面
我在Web MVC中使用带有OWIN身份validation的Web API。 我在Web.Config中使用为我的Web MVC,所以它重定向到登录页面。
我正在使用[System.Web.Http.Authorize]
属性来授权我的Web API。 但不知何故,由于上述配置,API重定向到登录页面,就像我的MVC应用程序一样。
我想要做的是保持重定向Web MVC的function,但返回401 for Web API。 我怎样才能做到这一点? 我应该为Web API创建自定义授权属性吗?
– 编辑 –
我发现WebApi.Owin中这篇文章中的SuppressDefaultHostAuthentication的答案也抑制了webapi之外的身份validation
所以我只需在Startup.cs
添加几行代码。 我的所有控制器都配置了“api”前缀路由。
HttpConfiguration config = new HttpConfiguration(); //..some OWIN configuration app.Map("/api", inner => { inner.UseWebApi(config); });
确保在Web Api配置行之后放置app.Map()
。 否则,它将给MVC应用程序带来错误。
创建自定义AuthorizeAttribute
:
public class MyAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) { actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized"); } }
如果您将来跳过web.config并使用owin来设置身份validation,您可以在Startup.cs
执行以下操作:
var provider = new CookieAuthenticationProvider(); var originalHandler = provider.OnApplyRedirect; provider.OnApplyRedirect = context => { if (!context.Request.Uri.LocalPath.StartsWith(VirtualPathUtility.ToAbsolute("~/api"))) { context.RedirectUri = new Uri(context.RedirectUri).PathAndQuery; originalHandler.Invoke(context); } }; app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, CookieName = FormsAuthentication.FormsCookieName, LoginPath = new PathString("/Account/LogOn"), ExpireTimeSpan = TimeSpan.FromMinutes(240), Provider = provider });
这对我有用。
创建自定义属性:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class NoRedirectAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) { actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Forbidden); } }
使用控制器中的属性:
[HttpDelete] [NoRedirectAuthorizeAttribute(Roles = "Admin")] [Route("api/v3/thingstodelete/{id=id}")] public IHttpActionResult DeleteThingToDelete(Guid id) { //delete code }
这里只是重写AuthorizeAttribute的HandleUnauthorizedRequest方法。 因此,我们不发送重定向(304)到登录页面,而是发送Forbidden(403)HTTP状态代码。
为了根据URL定义的约定更改IIS的行为方式,您需要分支OWIN管道。 您可以使用IApplicationBuilder.Map
来完成此IApplicationBuilder.Map
。 假设一个静态config
:
public void Configure(IApplicationBuilder app) { ... app.Map("/api", HandleWebApiRequests); ... } private static void HandleWebApiRequests(IApplicationBuilder app) { app.UseWebApi(config); }
Map
方法基于以"/api"
开头的URL将管道分支到HandleWebApiRequests
方法。
这应该导致401错误的行为像它们应该的那样,并且只返回401而没有重定向。
我需要配置StatusCodePage中间件以避免重定向
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ... app.UseStatusCodePages(); ... }