ASP.NET MVC 4 WebAPI authorization / Authorize attribute not working

5683
Views
1
Answers

I am trying to implement authorization attribute on my Web API controllers but it is not working. Some how this is not getting hit and the action is returning the expected status code of 401 (Unauthorized). But this authorization attribute is perfectly working with MVC controllers.

edit | flag
William Patrick
Asked on: Mar 21, 2012 at 7:21PM

1 Answers

134
6
134

So you have added [Authorize] attribute to your web Api controller and it is not returning the status code as expected.

Ok lets get it working.. before that please make sure that you use System.Web.Http.AuthorizeAttribute from System.Web.Http.dll for Web API instead of System.Web.Mvc.AuthorizeAttribute from System.Web.Mvc.dll

If you are expecting a status code of 401 to be returned in client during your Ajax calls and it is sending a 302 status code instead.

Lets create some folder called App_auth folder or any folder you choose and add two classes to it.

Now Set the marker in PostReleaseRequestState - (Occurs when ASP.NET has completed executing all request event handlers and the request state data has been stored). event if this is an ajax request and if our action returns status code equals to 401 (Unauthorized) or 403 (Forbidden).

Then on OnEndRequest-(Occurs as the last event in the HTTP pipeline chain of execution when ASP.NET responds to a request.) lets check if marker exists, and if yes, then set the returned status code from an action.

Class AjaxAuthentication:

     public class AjaxAuthenticationModule : IHttpModule
       
{

           
private const string FixupKey = "__WEBAPI:Authentication-Fixup";

           
public void Dispose()
           
{

           
}

           
public void Init(HttpApplication context)
           
{

                context
.PostReleaseRequestState += OnPostReleaseRequestState;

                context
.EndRequest += OnEndRequest;

           
}

           
//Set the marker in PostReleaseRequestState event if this is an ajax request and if our action returns
           
//status code equals to 401 (Unauthorized) or 403 (Forbidden)
           
private void OnPostReleaseRequestState(object source, EventArgs args)
           
{

               
var context = (HttpApplication)source;

               
var response = context.Response;

               
var request = context.Request;

               
bool isAjax = request.Headers["X-Requested-With"] == "XMLHttpRequest";

               
if ((response.StatusCode == 401 || response.StatusCode == 403) && isAjax)
               
{

                    context
.Context.Items[FixupKey] = response.StatusCode;

               
}

           
}

           
// OnEndRequest check if marker exists, and if yes, then set the returned status code from an action back.
           
private void OnEndRequest(object source, EventArgs args)
           
{

               
var context = (HttpApplication)source;

               
var response = context.Response;

               
if (context.Context.Items.Contains("__WEBAPI:Authentication-Fixup"))
               
{

                    response
.StatusCode = (int)context.Context.Items[FixupKey];

                    response
.RedirectLocation = null;

               
}

           
}

       
}

Then the Class to start the bind the method during application start up using PreApplicationStartMethod and DynamicModuleUtility which inherits from Microsoft.Web.Infrastructure.DynamicModuleHelper

To install Microsoft.Web.Infrastructure.DynamicModuleHelper using Nuget Package manager console run this command in Project manager console

PM> Install-Package Microsoft.Web.Infrastructure

add the code to the class AuthenticationFixer

[assembly: PreApplicationStartMethod(typeof(AuthenticationFixer), "Start")]

namespace YourNamespace.Web.App_auth
{
   
public static class AuthenticationFixer
   
{
       
public static void Start()
       
{
           
DynamicModuleUtility.RegisterModule(typeof(AjaxAuthenticationModule));
       
}
   
}
}

Now you will get the expected 401(UnAuthourized) status code in your client.

Try this Ajax call to get the expected result after decorating your action/ controller with [Authorize] attribute

 $.ajax({ url: "/api/apicontroller",
            accepts
: "application/json",
            cache
: false,
            statusCode
: {
               
200: function (data) {
                   alert
('Ok');;
               
},
               
401: function (data) {
                    alert
('unauthorized 401');
               
}
           
}
       
});
edit | flag
Gokul A
Answered on: Mar 21, 2012 at 8:07PM

Post your Answer

Search

Welcome to Ask Amoeba!
This is 100% free and interactive site for sharing professional Questions and Answers, Opensource projects, Interview questions.
Learners, beginners, Experts stop and share your knowledge and ideas!

Browse Categories

Browse Tags