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

时间:2015-01-26 09:27:33

标签: asp.net-web-api asp.net-identity asp.net-web-api2 owin asp.net-identity-2

在某些控制器中,我想根据公司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网址值?

这里可以[Authorize]以某种方式使用吗?

2 个答案:

答案 0 :(得分:2)

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

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")]

答案 1 :(得分:0)

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