Zholen
Zholen

Reputation: 1790

Custom Authorize for both action and api calls?

I recently asked this question and have successfully setup my custom authorize attribute.

But now I have hit another wall regarding api calls. I need these calls to also be authorized in the same fashion as the action calls. I understand that there is a difference between System.Web.Http and System.Web.Mvc Authorize attributes. So I have created a separate Api specific attribute that basically does the same thing. However, I am having trouble setting the User - principal and identity like i do in the original attribute.

My attributes simply check for some values in a cookie to authorize the request, once the attribute has read the cookie I was storing the decrypted cookie information within a custom principal/identity setup. In my Api call, when I go to retrieve this information from the identity my cast fails and i receive a null value.

This is how I store the information

Api

HttpContext.Current.User = new MyPrinciple(new MyIdentity(decCookie.Name, decCookie.UserData));

Action

filterContext.RequestContext.HttpContext.User = new MyPrinciple(new MyIdentity(decCookie.Name, decCookie.UserData));

How I retrieve the desired information I assumed would be the same

(User.principal.Identity as MyIdentity).MyData;

Questions

  1. Do I really need to have 2 separate attributes
  2. For the Api attribute how can I easily store the information for later use within the controller. Or basically can I not actually get/set the Identity this way for these calls?

EDIT #1

I found how to properly access my cookie value from my ApiController, I was simply missing a reference to System.Web >_<. So question #2 has been solved! but #1 still remains.

Upvotes: 1

Views: 1251

Answers (2)

Slicksim
Slicksim

Reputation: 7172

You can only inherit in one class from in c#, and each authorizeattribute lives in its own namespace, so you can't do it in a single class.

You could hold it in a common namespace and then call a common class to do the lifting.

Possible solution (untested)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace Common.Attributes
{
public class CustomAuthorize : System.Web.Mvc.AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if (!HttpContext.Current.Request.IsAuthenticated || (HttpContext.Current.User as User) != null)
            return;

        filterContext.HttpContext.User = Authorize.ExtractIdentity(filterContext.HttpContext);
    }
}

public class CustomHttpAuthorize : System.Web.Http.AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        base.OnAuthorization(actionContext);

        if (!HttpContext.Current.Request.IsAuthenticated || (HttpContext.Current.User as User) != null)
            return;

            System.Threading.Thread.CurrentPrincipal = Authorize.ExtractIdentity(filterContext.HttpContext);
        }
    }  
}

public static class Authorize
{
    public static IIdentity ExtractIdentity(HttpContext context)
    {
        // do your magic here
    }
}
}

Upvotes: 1

leastprivilege
leastprivilege

Reputation: 18482

Web API and MVC have nothing in common (technically) - even when they look the same. You need two separate attributes.

Upvotes: 3

Related Questions