基于声明的授权以及在何处添加用户可以执行的操作
Claims-based authorization and where to add what the user can do
我刚刚使用基于声明的授权实现了一个网络 api。用户可以登录系统,并根据用户可以执行的操作从数据库中提取一组声明并添加到 httpContext.User.Identity。
在 Startup.cs 中注册策略后,使用如下内容:
services.AddAuthorization(options =>
{
options.AddPolicy(PoliciesDefinitions.RequiresVehicleList, policy => policy.RequireClaim(Permissions.VehiclesList.ToString()));
...
});
我可以在我想要授权的控制器方法上使用 Authorize 属性,例如:
Authorize(Policy=PoliciesDefinitions.RequiresDriversList)]
[HttpGet]
public ActionResult Get() { ... }
这工作正常,但今天我更彻底地阅读了微软文档,我在基于声明的授权文档中看到了这个声明:
A claim is a name value pair that represents what the subject is, not
what the subject can do
此时我正在做 microsfot 建议不要做的事情。我将用户可以执行的操作(权限)添加到 identity 中。所以,这让我思考,我做错了吗?如果答案是肯定的,您将在哪里存储用户权限以及授权如何工作?
这允许 KVP 和多个值。
// with Razor, you did not specific if it was core 2, 3.1 or Razor
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.AddPolicy("Vendors", policy =>
policy.RequireClaim("Type.Tykt.org", "Dealer", "Driver", "WholeSaler", "Asset", "Repair"));
});
}
选项 2:
还有一个claims
合集,可以在用户登录成功后添加。
var user = new User {
Email = "xyz@tykt.org",
Name = "xyz"
}
user.Claims.Add(new IdentityUserClaim<string>
{
ClaimType="your-type", // your key
ClaimValue="your-value" // your value
});
await userManager.CreateAsync(user);
更新Ref MSDN:
这实际上是您对如何存储检索的选择,如果我理解这个问题,您的具体问题是索赔的价值。
通常,映射和验证以类似 PermissionHandler : IAuthorizationHandler
或通用方法 MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
的方式进行。其中,加载值,并处理特定权限的需求验证,例如最小年龄,但实际声明(你在说什么/min age policy
vs 值通常在数据库中,如 DOB=1/1/1990
)与 Principal
对象。现在,您可以选择从何处检索声明的价值
在下面的函数中,他从上下文中获取键的值,然后验证
public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
MinimumAgeRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth &&
c.Issuer == "http://contoso.com"))
{
return Task.CompletedTask;
}
var dateOfBirth = Convert.ToDateTime(
// He gets the value on the server-side from any store or 3rd party relayer
context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth &&
c.Issuer == "http://contoso.com").Value);
int calculatedAge = DateTime.Today.Year - dateOfBirth.Year;
if (dateOfBirth > DateTime.Today.AddYears(-calculatedAge))
{
calculatedAge--;
}
if (calculatedAge >= requirement.MinimumAge)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
我刚刚使用基于声明的授权实现了一个网络 api。用户可以登录系统,并根据用户可以执行的操作从数据库中提取一组声明并添加到 httpContext.User.Identity。
在 Startup.cs 中注册策略后,使用如下内容:
services.AddAuthorization(options =>
{
options.AddPolicy(PoliciesDefinitions.RequiresVehicleList, policy => policy.RequireClaim(Permissions.VehiclesList.ToString()));
...
});
我可以在我想要授权的控制器方法上使用 Authorize 属性,例如:
Authorize(Policy=PoliciesDefinitions.RequiresDriversList)]
[HttpGet]
public ActionResult Get() { ... }
这工作正常,但今天我更彻底地阅读了微软文档,我在基于声明的授权文档中看到了这个声明:
A claim is a name value pair that represents what the subject is, not what the subject can do
此时我正在做 microsfot 建议不要做的事情。我将用户可以执行的操作(权限)添加到 identity 中。所以,这让我思考,我做错了吗?如果答案是肯定的,您将在哪里存储用户权限以及授权如何工作?
这允许 KVP 和多个值。
// with Razor, you did not specific if it was core 2, 3.1 or Razor
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
services.AddAuthorization(options =>
{
options.AddPolicy("Vendors", policy =>
policy.RequireClaim("Type.Tykt.org", "Dealer", "Driver", "WholeSaler", "Asset", "Repair"));
});
}
选项 2:
还有一个claims
合集,可以在用户登录成功后添加。
var user = new User {
Email = "xyz@tykt.org",
Name = "xyz"
}
user.Claims.Add(new IdentityUserClaim<string>
{
ClaimType="your-type", // your key
ClaimValue="your-value" // your value
});
await userManager.CreateAsync(user);
更新Ref MSDN:
这实际上是您对如何存储检索的选择,如果我理解这个问题,您的具体问题是索赔的价值。
通常,映射和验证以类似 PermissionHandler : IAuthorizationHandler
或通用方法 MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
的方式进行。其中,加载值,并处理特定权限的需求验证,例如最小年龄,但实际声明(你在说什么/min age policy
vs 值通常在数据库中,如 DOB=1/1/1990
)与 Principal
对象。现在,您可以选择从何处检索声明的价值
在下面的函数中,他从上下文中获取键的值,然后验证
public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
MinimumAgeRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth &&
c.Issuer == "http://contoso.com"))
{
return Task.CompletedTask;
}
var dateOfBirth = Convert.ToDateTime(
// He gets the value on the server-side from any store or 3rd party relayer
context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth &&
c.Issuer == "http://contoso.com").Value);
int calculatedAge = DateTime.Today.Year - dateOfBirth.Year;
if (dateOfBirth > DateTime.Today.AddYears(-calculatedAge))
{
calculatedAge--;
}
if (calculatedAge >= requirement.MinimumAge)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}