Web Api 2:针对自定义声明进行授权

Web Api 2: Authorising against custom claims

在某些控制器中,我想根据公司 ID 授权用户。

例如,考虑以下资源:

api/v1/companies/1234/orders

这应该只能由属于公司 1234 的用户访问。

请注意,我使用的是 OAuth 令牌持有者身份验证。

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);
}

订单资源的当前控制器实现:

[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)));
    }
}

我在哪里根据身份声明授权 companyId URL 值?

这里可以用[Authorize]吗?

请参阅 https://github.com/AzureADSamples/NativeClient-DotNet/blob/master/TodoListService/Controllers/TodoListController.cs 中的方法 - 您可以使用自定义声明类型

而不是 "scope"

这是您可以使用的自定义授权过滤器

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;

    }

}

如果您只想让一家公司访问一个操作或控制器,您也可以用下面的方式装饰您的操作或控制器。

[AuthorizeAction(CompanyId = "1234")]