有没有办法有这样的东西?
options.AddPolicy("IsEducationOwner", policy =>
{
// Eather first OR second policy requirement needs to be true
policy.Requirements.Add(new EducationOwnerRequirement()); // My custom requirement that has one handler
policy.RequireRole("CatalogAdmin"); // Role based requirement
});
答案 0 :(得分:0)
我发现这很有效。需求需要有额外的处理程序来检查用户声明中的角色,因此代码看起来像这样。
其他信息可在this MSDN page或this article
中找到我的例子:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options => {
options.AddPolicy("IsEducationOwner", policy =>
{
policy.Requirements.Add(new EducationOwnerRequirement());
});
});
services.AddTransient<IAuthorizationHandler, IsEducationOwnerHandler>();
services.AddTransient<IAuthorizationHandler, HasCatalogAdminRoleHandler>();
}
}
public class EducationOwnerRequirement : IAuthorizationRequirement
{
}
public class HasCatalogAdminRoleHandler : AuthorizationHandler<EducationOwnerRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, EducationOwnerRequirement requirement)
{
if (context.User.IsInRole("CatalogAdmin"))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
public class IsEducationOwnerHandler : AuthorizationHandler<EducationOwnerRequirement>
{
private PerformaContext _db;
public IsEducationOwnerHandler(PerformaContext db)
{
_db = db;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, EducationOwnerRequirement requirement)
{
var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
if (mvcContext == null || !context.User.HasClaim(c => c.Type == ClaimTypeNaming.oid))
{
return Task.CompletedTask;
}
var path = mvcContext.HttpContext.Request.Path.Value;
var educationId = path.Substring(path.IndexOf("/api/educations/") + 16, path.Length - path.IndexOf("/api/educations/") - 16);
var userExternalId = context.User.FindFirst(ClaimTypeNaming.oid).Value;
var userId = _db.GetUserByExternalId(userExternalId).Select(x => x.Id).FirstOrDefault();
if(userId == Guid.Empty)
{
return Task.CompletedTask;
}
var educationOwners = _db.GetOwnersForEducation(Guid.Parse(educationId)).Select(x => x.UserId).ToList();
if (educationOwners.Contains(userId))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}