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")]
在某些控制器中,我想根据公司 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")]