Home > Enterprise >  403 on Succeed AuthorizationHandler aspnetcore
403 on Succeed AuthorizationHandler aspnetcore

Time:06-19

Trying to implement policy authorization in a .NET6 Web Api.

I've added in authentication and authorization via the configuration:

builder.AddCredibleApplicationFramework(assemblies);
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
    options =>
    {
        var tokenValidationSettings = builder.Configuration.GetSection("JwtSettings")
            .Get<TokenValidationSettings>();
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = tokenValidationSettings.ValidateIssuer,
            ValidateAudience = tokenValidationSettings.ValidateAudience,
            ValidateIssuerSigningKey = true,
            ValidIssuer = tokenValidationSettings.Issuer,
            IssuerSigningKey =
                new SymmetricSecurityKey(Encoding.ASCII.GetBytes(tokenValidationSettings.SigningKey))
        };
    });
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("isAdministrator",
    policyBuilder =>
    {
        policyBuilder.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
        policyBuilder.AddRequirements(new IsAdministratorRequirement());
    });
});
builder.Services.AddSingleton<IAuthorizationHandler, IsApplicationAdministratorHandler>();
builder.Services.AddDbContext<CDbContext>(options =>
{
var connection = builder.Configuration.GetConnectionString("conn");
options
    .UseMySql(connection, ServerVersion.AutoDetect(connection))
    .EnableSensitiveDataLogging()
    .EnableDetailedErrors()
    .UseLoggerFactory(loggerFactory);
});

var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();
app.MapControllers();
app.Run();

The handler success path is executing (the requirement succeeds):

    public class IsApplicationAdministratorHandler : AuthorizationHandler<IsAdministratorRequirement>
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
        IsAdministratorRequirement requirement)
        {
            if (context.User.HasClaim(c => c.Type.Equals("applicationAdmin")) ||
            context.User.HasClaim(c => c.Type.Equals("platformAdmin")))
            {
                return Task.FromResult(() => context.Succeed(requirement)); <-- This line returns....
            }
            return Task.FromResult(() => context.Fail());
        }
    }

I am getting 403 even though the handler succeeds.

CodePudding user response:

You are returning a lambda result rather than calling the actual context method, since your lambda is never executed. Its not necessary in your case, as you can directly call context.Succeed(requirement)

public class IsApplicationAdministratorHandler : AuthorizationHandler<IsAdministratorRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
    IsAdministratorRequirement requirement)
    {
        if (context.User.HasClaim(c => c.Type.Equals("applicationAdmin")) ||
        context.User.HasClaim(c => c.Type.Equals("platformAdmin")))
        {
            context.Succeed(requirement);
        }
        else
        {
            // this isn't strictly necessary, unless you want to fail hard and early 
            // and not give other policy handlers to be evaluated
            context.Fail(requirement)
        };

        return Task.Completed;
    }
}
  • Related