Question

I am fairly new to .net and I am trying to create a restfull service where you can authenticate via OAuth2 to a service like facebook and also be able to login with a "normal account". The SPA template from VS2013 allowed me to do this quickly and easily and I am very happy with it.

Right now I am facing a different problem. I can't seem to find a way to separate access for these different types of logins. For example, I want to allow only users from the oauth authentication method to access X and users that authenticated in the "normal way" (also with a bearer token) to be able to see only Y.

I searched the web and it seems that I should be using the [Authorize] tag but I am not sure how to customize it nor differentiate between different logins. I found different methods of customizing the tag but none seem to be working and I keep stumbling into solutions that are out of date.

Can anyone help?

Thank you!


My final solution (thanks to 0leg)

Created an authorize tag for each authentication type:

public class AuthorizeExternalsOnly : AuthorizeAttribute
{
    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
    {

        if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
        {
            string externalClaim = "";
            try
            {
                externalClaim = (actionContext.ControllerContext.RequestContext.Principal.Identity as ClaimsIdentity).Claims.FirstOrDefault(x => x.Type == ClaimTypes.Authentication).Value;
            }
            catch (NullReferenceException)
            {
                Debug.WriteLine("no external claim found");
            }
            if (externalClaim != "")
            {
               return base.IsAuthorized(actionContext);
            }
            return false;
        }
        return false;
    }
}

At the account controler I then added the claim's at GetExternalLogin

oAuthIdentity.AddClaim(new Claim(ClaimTypes.Authentication, "External"));
(...)
identity.AddClaim(new Claim(ClaimTypes.Authentication, "External"));

right before each sign in.

Was it helpful?

Solution

You can create a Claim to define your user type (internal, facebook, etc). Then create a custom Authorize attribute to make the authorization decision.

Look at this, this and this links for some background info.

Code sample for custom Authorize attribute. HttpActionContext parameter lets you see what controller and action you called. It also lets you inspect the Claims collection for your user. Step through the code for the different login scenarios, you'll have different claims. Then you can decide whether your Controller.Action is authorized for a particular claim value.

protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
    ActionName = actionContext.ActionDescriptor.ActionName,
    ControllerName = actionContext.ControllerContext.ControllerDescriptor.ControllerName,
    Claims = (actionContext.RequestContext.Principal.Identity as ClaimsIdentity).Claims.ToList()
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top