I am working on an ASP.NET 6 POC and I am checking if I can migrate to minimal APIs and FastEndpoints.
I am interested in using only authentication against an Azure AD tenant and my relevant configuration is as follows:
services.AddFastEndpoints();
services.AddMicrosoftIdentityWebApiAuthentication(configuration);
services.AddEndpointsApiExplorer();
services.AddSwaggerDoc(c =>
{
AddSwaggerDocs_ConfigureAuth(c, auth);
}, addJWTBearerAuth: false);
c.AddAuth("oauth2", new OpenApiSecurityScheme
{
Type = OpenApiSecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow()
{
AuthorizationUrl = $"{auth.Instance}/{auth.TenantId}/oauth2/v2.0/authorize",
TokenUrl = $"{auth.Instance}/{auth.TenantId}/oauth2/v2.0/token",
Scopes = { { $"api://{auth.ClientId}/access_as_user", "Access as user" } }
}
}
});
var app = builder.Build();
app.UseAuthorization();
app.UseFastEndpoints();
app.UseOpenApi();
app.UseSwaggerUi3(c =>
{
c.ConfigureDefaults();
c.OAuth2Client = new OAuth2ClientSettings
{
ClientId = auth.ClientId,
AppName = "Foo - Swagger",
UsePkceWithAuthorizationCodeGrant = true
};
});
This correctly configures Swagger and I am able to get a token from my Azure AD:
My test endpoint is the following:
public class GetWeatherEndpoint : Endpoint<GetWeatherInput, List<WeatherForecast>>
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public override void Configure()
{
Get("weather/{days:int}");
}
public override async Task HandleAsync(GetWeatherInput input, CancellationToken token)
{
var response = Enumerable.Range(1, input.Days).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToList();
await SendOkAsync(response, token);
}
}
If I try to call this, I receive a 401, as authorization is enabled by default. If I add AllowAnonymous()
, it works as expected (HandleAsync
gets called).
When working with controllers, a simple Authorized
attribute would make things work.
Any idea about how to properly configure the endpoint in this case?
this is most likely a minor misconfiguration.
in order to see why exactly the auth middleware is sending a 401 response, you'd have to do something similar to what's being done in this article to log the reason.
basically you need to tap in to a hook like OnAuthenticationFailed
and log the reason for failure.
it seems the request is not reaching fastendpoints due to the auth middleware interrupting the flow earlier on.
maybe try the subscribeToJwtBearerMiddlewareDiagnosticsEvents
in AddMicrosoftIdentityWebApiAuthentication
also don't you need a app.UseAuthentication()
call with azure ad?