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

时间:2016-12-09 08:29:07

标签: asp.net authorization asp.net-core-1.0

有没有办法有这样的东西?

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

1 个答案:

答案 0 :(得分:0)

我发现这很有效。需求需要有额外的处理程序来检查用户声明中的角色,因此代码看起来像这样。

其他信息可在this MSDN pagethis 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;
    }
}