0

I am trying to to Minimal API in an ASP.NET Core app. I added the following endpoint

app.MapPost("api/content", CallbackAsync);

The defined the CallbackAsync as a static function as the following

[Authorize(AuthenticationSchemes = "Api")]
private static async Task<IResult> CallbackAsync(
    
    IAuthorizationService authorizationService,
    HttpContext httpContext)
{
    // ...

    return Results.Ok(...);
}

Authentication is failing. when I use controller, adding [Authorize(AuthenticationSchemes = "Api")] works but not with Minimal API.

How can I apply [Authorize(AuthenticationSchemes = "Api")] with minimal API?

1

3 Answers 3

2

If you have a minimal API you can either decorate your lambda for the .MapPost

app.MapGet("/weatherforecast2",
        [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        () =>
        {
            var forecast = Enumerable.Range(1, 5).Select(index =>
                    new WeatherForecast
                    (
                        DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                        Random.Shared.Next(-20, 55),
                        summaries[Random.Shared.Next(summaries.Length)]
                    ))
                .ToArray();
            return forecast;
        })
    .WithName("GetWeatherForecast2")
    .WithOpenApi()
    .RequireAuthorization("api");

if you have created the policy like this:

builder.Services.AddAuthorizationBuilder()
    .AddPolicy("api", p => p.RequireRole("Role"));

then you can create the policy like this programmactly:

app.MapGet("/weatherforecast", () =>
    {
        var forecast = Enumerable.Range(1, 5).Select(index =>
                new WeatherForecast
                (
                    DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                    Random.Shared.Next(-20, 55),
                    summaries[Random.Shared.Next(summaries.Length)]
                ))
            .ToArray();
        return forecast;
    })
    .WithName("GetWeatherForecast")
    .WithOpenApi()
    .RequireAuthorization(auth =>
    {
        auth.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
        auth.RequireRole("Role");
    });

only thing to remember is that you cannot refer to your added policies in the builder.Services.AddAuthorizationBuilder command


PS. For future googlers, is it possible to refer a the created policy named "api" when doing the RequireAuthorization with lambda config?

Sign up to request clarification or add additional context in comments.

Comments

0

you need to configure authentication middleware explicitly. UseAuthentication() and UseAuthorization() adds required middlewares to the pipeline.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

// Add authentication middleware
app.UseAuthentication();

// Add authorization middleware
app.UseAuthorization();

app.MapPost("api/content", CallbackAsync);

app.Run();

[Authorize(AuthenticationSchemes = "Api")]
private static async Task<IResult> CallbackAsync(
    IAuthorizationService authorizationService,
    HttpContext httpContext)
{
    // ...

    return Results.Ok(...);
}

Comments

0

Similar to a standard controller attribute. In Program.cs file,

builder.Services.AddAuthentication().AddJwtBearer("api");
builder.Services.AddAuthorizationBuilder()
  .AddPolicy("api", policy =>
        policy
            .RequireRole("admin")
            .RequireClaim("scope", "api/content"));

var app = builder.Build();

app.MapPost("api/content", (HttpContext context, 
                           IOtherDependency otherDependency, 
                           CallBackAsyncClass callBackAsyncClass) => 
    callBackAsyncClass.CallBackAsync(otherDependency, context))
    .RequireAuthorization("api");

app.UseAuthentication();
app.UseAuthorization();

For additional information this link should be helpful.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/security?view=aspnetcore-8.0

Ensure that any other dependencies that rely on DI are also injected using

builder.Services.AddScoped<IDependency, Dependency>();

The DI part should remain the same.

1 Comment

RequireAuthorization("api") is using the api policy not the AuthenticationSchemes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.