Make web API authentication 401 instead of redirecting to login page

I have a web API with OWIN authentication in web MVC. I use <authentication> in Web.Config for my web MVC, so it redirects to the login page.

 <authentication mode="Forms"> <forms name="WEB.AUTH" loginUrl="~/login" domain="" protection="All" timeout="43200" path="/" requireSSL="false" slidingExpiration="true" /> </authentication> 

I use the [System.Web.Http.Authorize] attribute to authorize my web API. But for some reason, the API redirects the login page in the same way as my MVC application due to the above configuration.

what I want to do is keep the redirect function for web MVC, but returns 401 for web API. How can i achieve this? Should I create a custom authorization attribute for the web API?

- EDIT -

I found the answer from this post SuppressDefaultHostAuthentication in WebApi.Owin also suppresses authentication outside of webapi

So, I just add a few lines to my Startup.cs . I had all my controllers configured with the api prefix.

 HttpConfiguration config = new HttpConfiguration(); //..some OWIN configuration app.Map("/api", inner => { inner.UseWebApi(config); }); 

make sure you put app.Map() after the web api configuration lines. Otherwise, the MVC application will fail.

+5
source share
2 answers

Create a custom AuthorizeAttribute :

 public class MyAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) { actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized"); } } 

If in the future you skip the web.config file and use owin to configure your authentication, you can do in 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 }); 
+1
source

This is what worked for me.

Creating a custom attribute:

 [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); } } 

Using an attribute in your controller:

  [HttpDelete] [NoRedirectAuthorizeAttribute(Roles = "Admin")] [Route("api/v3/thingstodelete/{id=id}")] public IHttpActionResult DeleteThingToDelete(Guid id) { //delete code } 

Here, the HandleUnauthorizedRequest AuthorizeAttribute method is simply overridden. Therefore, instead of sending redirects (304) to the login page, we send an HTTP status code with a ban (403).

0
source

Source: https://habr.com/ru/post/1240930/


All Articles