Dbl
Dbl

Reputation: 5914

Custom AuthorizationHandler HandleRequirementAsync not called

I can't figure out why my authorization won't succeed.

I found this while looking into potential reasons:

https://github.com/aspnet/Security/issues/1103

Seems like OP had a similar issue, though my issue isn't even related to resource based authorization.

Here's my code:

AuthorizationHandler:

public class DebugOrDeveloperRequirementHandler : AuthorizationHandler<DebugOrDeveloperRequirement>
{
    private readonly IHostingEnvironment _environment;

    public DebugOrDeveloperRequirementHandler(IHostingEnvironment environment)
    {
        // breakpoint here - does get hit
        _environment = environment;
    }

    /// <inheritdoc />
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DebugOrDeveloperRequirement requirement)
    {
        // breakpoint here but never hit
        if (_environment.IsDevelopment() || _environment.IsIntegrationTest() || context.User.IsInRole(Constants.RoleNames.Developer))
            context.Succeed(requirement);

        return Task.CompletedTask;
    }
}

requirement:

public class DebugOrDeveloperRequirement : IAuthorizationRequirement
{

}

Startup.cs code:

        services.AddAuthorization(config =>
        {
            config.AddPolicy(ApplicationPolicyNames.Contractor, builder =>
            {
                builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                    .RequireAuthenticatedUser()
                    .RequireRole(DataLayer.Setup.Constants.RoleNames.Contractor, DataLayer.Setup.Constants.RoleNames.Developer, DataLayer.Setup.Constants.RoleNames.Admin);
            });

            config.AddPolicy(ApplicationPolicyNames.Customer, builder =>
            {
                builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                    .RequireAuthenticatedUser()
                    .RequireRole(DataLayer.Setup.Constants.RoleNames.Customer, DataLayer.Setup.Constants.RoleNames.Developer, DataLayer.Setup.Constants.RoleNames.Admin);
            });

            config.AddPolicy(ApplicationPolicyNames.Administrator, builder =>
            {
                builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                    .RequireAuthenticatedUser()
                    .RequireRole(DataLayer.Setup.Constants.RoleNames.Developer, DataLayer.Setup.Constants.RoleNames.Admin);
            });

            config.AddPolicy(ApplicationPolicyNames.Developer, builder =>
            {
                builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                    .RequireAuthenticatedUser()
                    .RequireRole(DataLayer.Setup.Constants.RoleNames.Developer);
            });

            config.AddPolicy(ApplicationPolicyNames.DeveloperOrDebug, builder =>
            {
                builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                    .Requirements.Add(new DebugOrDeveloperRequirement());
            });
        });
services.AddSingleton<IAuthorizationHandler, DebugOrDeveloperRequirementHandler>();

My code does not look all that different from documentation. Hence i can't really see why this AuthorizationHandler is not called.

Upvotes: 2

Views: 7774

Answers (1)

Dbl
Dbl

Reputation: 5914

Well now i feel silly - i thought action authorize attributes override controller attributes - they don't.

My controller had a Developer Policy - that made the action fail before that handler even got to its execution turn.

Upvotes: 2

Related Questions