使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(); ... }