单个策略中的ASP.NET核心多重(类型)授权要求



有什么方法可以拥有这样的东西?

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 
});

我发现这在起作用。要求需要具有其他处理程序,以检查在用户索赔中的作用,因此代码看起来像这样。

其他信息可以在此MSDN页面或本文中找到

我的示例:

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;
    }
}

最新更新