In certain controllers, I want to authorize a user against a company ID.
For example, consider the following resource:
api/v1/companies/1234/orders
This should only be accessible by users who belong to company 1234.
Note that I am using OAuth token bearer authentication.
Creating the company claim in OAuthAuthorizationServerProvider
:
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
//...
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
// Creating the companyId claim
identity.AddClaim(new Claim("CompanyId", user.CompanyId.ToString()));
context.Validated(identity);
}
The current controller implementation for the orders resource:
[RoutePrefix("api/v1/companies/{companyId:Guid}/orders")]
public class OrdersController : ApiController
{
[Route]
public IHttpActionResult GetOrders(Guid companyId)
{
var orders = OrdersRepository.Get(companyId);
return Ok(orders.Select(x => OrderModel.From(x)));
}
}
Where do I authorize the companyId URL value against the identity claim?
Can [Authorize]
be somehow used here?
Here is a custom authorize filter you could use
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
public class AuthorizeAction : AuthorizeAttribute {
public string CompanyId;
protected override bool IsAuthorized(HttpActionContext actionContext) {
if (String.IsNullOrEmpty(CompanyId))
{
var routeData = actionContext.Request.GetRouteData();
var myId = routeData.Values["CompanyId"] as string;
CompanyId = myId;
}
var user = actionContext.RequestContext.Principal as ClaimsPrincipal;
if (user == null || !user.Identity.IsAuthenticated)
return false;
if (user.Claims.Any(claim => claim.Type.Equals("CompanyId") && claim.Value.Equals(CompanyId)))
return true;
return false;
}
}
You could also decorate your action or controller with below if you wanted only a single company to access a action or controller.
[AuthorizeAction(CompanyId = "1234")]