[英]Claims-based authorization and where to add what the user can do
I just implemented a web api using claims-based authorization.我刚刚使用基于声明的授权实现了 web api。 A user can login in the system and a set of claims are pulled from the database and added to the httpContext.User.Identity depending on what the user can do.用户可以登录系统,然后根据用户可以执行的操作从数据库中提取一组声明并添加到 httpContext.User.Identity。
After registering the policies in Startup.cs with something like:在 Startup.cs 中注册策略后,使用以下内容:
services.AddAuthorization(options =>
{
options.AddPolicy(PoliciesDefinitions.RequiresVehicleList, policy => policy.RequireClaim(Permissions.VehiclesList.ToString()));
...
});
I can use the Authorize attribute on the controllers method that I want to authorize with something like:我可以在要授权的控制器方法上使用 Authorize 属性,例如:
Authorize(Policy=PoliciesDefinitions.RequiresDriversList)]
[HttpGet]
public ActionResult Get() { ... }
This works ok but today I was reading microsoft documentation a bit more thoroughly and I came across this statement in the Claims-based authorization documentation:这工作正常,但今天我更彻底地阅读了微软文档,我在基于声明的授权文档中遇到了这个声明:
A claim is a name value pair that represents what the subject is, not what the subject can do声明是一个名称值对,表示主题是什么,而不是主题可以做什么
At this time I'm doing exactly what microsfot suggests not to do.目前,我正在做 microsfot 建议不要做的事情。 I'm adding what the user can do (permissions) to the identity.我正在将用户可以做的事情(权限)添加到身份中。 So, this leads me to think, am I doing it wrong?所以,这让我想,我做错了吗? If the answer is yes, where would you store the user permissions and how would authorization work?如果答案是肯定的,您将在哪里存储用户权限以及授权如何工作?
This allows for the KVP, and multiple values.这允许 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"));
});
}
Option 2:选项 2:
Also there is a claims
collection, you can add it after user successfully logs in.还有一个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);
Its really your choice on how you store retrieve, if I'm understanding the question, your question specifically around is the value of the claim.如果我理解这个问题,那么您对如何存储检索确实是您的选择,那么您的问题就是索赔的价值。
Typically, the mapping and verification happens in something like a PermissionHandler: IAuthorizationHandler
or a generic approach MinimumAgeHandler: AuthorizationHandler<MinimumAgeRequirement>
.通常,映射和验证发生在PermissionHandler: IAuthorizationHandler
或通用方法MinimumAgeHandler: AuthorizationHandler<MinimumAgeRequirement>
中。 Which, loads the values, and handles the requirement verification of a specific permission for eg min age, but the actual claims (what are you stating/ min age policy
vs the value is usually in the DB, like DOB= 1/1/1990
) travel with the Principal
object.其中,加载值,并处理特定权限的要求验证,例如最小年龄,但实际声明(您在说明什么/ min age policy
与值通常在数据库中,如 DOB= 1/1/1990
) 与Principal
object 一起旅行。 Now, where you choose to retrieve the value of the claim is upto you现在,您选择在哪里检索索赔的价值取决于您
In the below function he is getting value for the Key from the Context and then validating在下面的 function 中,他从 Context 中获取 Key 的值,然后进行验证
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.