Tal Humy
Tal Humy

Reputation: 1227

.Net Web Api - Override AuthorizationFilter

Hello I have a web api controller inside a mvc web site. I'm trying to allow access to the controller using 2 rules: User is admin or the request came from local computer;

I'm new to AuthorizationFilterAttribute but I tried to write one that limit access to local request only:

public class WebApiLocalRequestAuthorizationFilter : AuthorizationFilterAttribute
{

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }
        if (actionContext.Request.IsLocal())
        {
            return;
        }
        actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        actionContext.Response.Content = new StringContent("Username and password are missings or invalid");
    }
}

Then I decorated my controller with 2 attributes as

[Authorize(Roles = "Admin")]
[WebApiLocalRequestAuthorizationFilter]
public class ContactController : ApiController
{
    public ContactModel Get(int id)
    {
        ContactsService contactsService = new ContactsService();
        return contactsService.GetContactById(id).Map<ContactModel>();
    }

}

But as I suspected , now, in order to access the controller I need to be admin and the request should be made from localhost. How can I do it?

Kind regards, Tal Humy

Upvotes: 1

Views: 713

Answers (1)

CooncilWorker
CooncilWorker

Reputation: 415

One solution is to create a class that inherits from AuthorizeAttribute

e.g. something like this

public class MyAuthorizeAttribute: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool accessAllowed = false;
        bool isInGroup = false;

        List<string> roleValues = Roles.Split(',').Select(rValue => rValue.Trim().ToUpper()).ToList();

        foreach (string role in roleValues)
        {
            isInGroup = IdentityExtensions.UserHasRole(httpContext.User.Identity, role);
            if (isInGroup)
            {
                accessAllowed = true;
                break;
            }
        }

        //add any other validation here
        //if (actionContext.Request.IsLocal()) accessAllowed = true;

        if (!accessAllowed)
        {
            //do some logging
        }

        return accessAllowed;
    }
...
}

Then you can use it like so:

[MyAuthorizeAttribute(Roles = "Support,Admin")]

In the above code, IdentityExtensions checks for, and caches, ActiveDirectory roles which also allows us to fake the current user having roles by changing the cache.

Upvotes: 3

Related Questions