您可以像这样创建自定义策略,您可以拥有多个单独的策略并将它们与授权标签堆叠在一起,或者您可以使用一个处理程序来处理多个策略,或者在一个策略中您可以在
policyBuilder(我喜欢这种方法用于很多用例)。请参阅下面的信息和微软链接
注册自定义策略的示例:
Startup.cs
services.AddAuthorization(authorizationOptions =>
{
authorizationOptions.AddPolicy(
"MustBeBornInSummer",
policyBuilder =>
{
//add any other policy requirements here too including ones by default
//eg policyBuilder.RequireAuthenticatedUser();
policyBuilder.AddRequirements(
new MustBeBornInSummerRequirement()
//, new AnotherRequirement()
);
});
//only if you want to register as the default policy
authorizationOptions.DefaultPolicy = authorizationOptions.GetPolicy("MustBeBornInSummer");
});
然后在授权中
你使用的标签
[Authorize("MustBeBornInSummer")]
您可以设置默认策略,允许您正常使用授权标签
authorizationOptions.DefaultPolicy = authorizationOptions.GetPolicy("MustBeBornInSummer");
您的需求类别
public class MustBeBornInSummerRequirement : IAuthorizationRequirement
{
public MustBeBornInSummerRequirement ()
{
}
}
处理程序类
public class MustBeBornInSummerHandler: AuthorizationHandler<MustBeBornInSummerRequirement>
{
public MustBeBornInSummerHandler ()
{
//your dependency injections
}
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MustBeBornInSummer requirement)
{
//Get the claim you want
var subject = context.User.Claims.FirstOrDefault(c => c.Type == "sub")?.Value;
var dateOfBirth = _useryRepository.GetApplicationUserProfile(subject)?.dob;
//your logic`check user claims then do stuff, or/and check roles too
if (!bornInSummer)
{
context.Fail();
return Task.CompletedTask;
}
// has claims
context.Succeed(requirement);
return Task.CompletedTask;
}
}
在你的配置服务中你需要注册它:
services.AddScoped<IAuthorizationHandler, MustBeBornInSummerHandler>();
您也可以拥有一个处理多个需求的处理程序
public class PermissionHandler : IAuthorizationHandler
{
public Task HandleAsync(AuthorizationHandlerContext context)
{
var pendingRequirements = context.PendingRequirements.ToList();
foreach (var requirement in pendingRequirements)
{
if(requirementMustBeBornInSummer
//Dostuff continue
elseIf(requirementIsBlah)
}
}
}
如何处理索赔由你决定,这是我通常的做法
var subject = context.User.Claims.FirstOrDefault(c => c.Type == "sub")?.Value;
var dateOfBirth = _useryRepository.GetApplicationUserProfile(subject)?.dob;
//My repository
public ApplicationUserProfile GetApplicationUserProfile(string subject)
{
return _context.ApplicationUserProfiles.FirstOrDefault(a => a.Subject == subject);
}
您还可以拥有单独的策略并将它们堆叠起来
[Authorize(Policy = "MustBeBornInSummer")]
[Authorize(Policy = "readRole")]
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-3.1
至于在 JWT 中存储大量数据,对于特定于应用程序的声明,我通常会创建一个表来存储特定应用中用户的声明。然后我使用令牌的“子”来查找用户拥有的声明。这使您无需返回非常大的令牌。