Allow anonymouos access to healthcheck endpoint when authentication fallback policy is set in ASP.NET Core 3
Asked Answered
M

3

30

asp.net core 3 allows to set FallbackPolicy to make the endpoints secure by default:

            services.AddAuthorization(options =>
            {
                options.FallbackPolicy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
            });

It is a great feature, but I have a HealthCheck endpoint too, that requires Authorization now.

            services.AddHealthChecks();
            [...]
            app.UseEndpoints(endpoints => {
                endpoints.MapHealthChecks("/health");
                endpoints.MapControllers();
            });

How do I allow anonymous access to the HealthCheck endpoint (NO authentication or authorization)?

Marginal answered 18/12, 2019 at 8:15 Comment(0)
T
52

I ran into exactly the same issue so I hope this helps as a more satisfactory way of achieving:

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute().RequireAuthorization();

            endpoints.MapHealthChecks("/health").WithMetadata(new AllowAnonymousAttribute());

        });
Triaxial answered 17/2, 2020 at 12:28 Comment(2)
Appears to be the better anwser, as the point of these changes seems to be to reduce the significance of ordering of the calls during startup.Zephyr
For people coming here in dotnet 7 or later, where UseEndpoints gives a warning, I think this is what we should do: app.MapHealthChecks("/health").AllowAnonymous();.Chaiken
F
50

Starting with .NET 5 there is a new clearer method for this - AllowAnonymous()

app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/health").AllowAnonymous();
    });
Fotheringhay answered 11/4, 2021 at 5:59 Comment(4)
Can be used directly, without UseEndpoint ilikeapp.MapHealthChecks("/health-check").AllowAnonymous();Podite
@Serg.ID, thanks! The WebApplication class returned by WebApplicationBuilder.Build() actually implements IEndpointRouteBuilder, too! So precisely the same MapHealthChecks implementation is used.Fragonard
AllowAnonymous docsFragonard
That worked for me. I had to add app.UseRouting(); before because I was having an error ("InvalidOperationException: EndpointRoutingMiddleware matches endpoints setup by EndpointMiddleware and so must be added to the request execution pipeline before EndpointMiddleware. Please add EndpointRoutingMiddleware by calling 'IApplicationBuilder.UseRouting'").Elna
L
21

You could invoke the HealthCheckMiddleware before using the AuthenticationMiddleware:

app.Map("/health",appbuilder =>{
    appbuilder.UseMiddleware<HealthCheckMiddleware>();
});
// or 
// app.UseHealthChecks("/health");


app.UseRouting();
// make sure the authentication middleware runs after the health check middleware
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});
Leannleanna answered 18/12, 2019 at 9:0 Comment(4)
This worked for me! I also needed to specify HealthCheckOptions, this can be done by creating an object healthCheckOptions and passing it so: appbuilder.UseMiddleware<HealthCheckMiddleware>(Options.Create(healthCheckOptions)); Another hint: In ConfigureServices method I also put AddHealthChecks call before configuring any authorization.Marginal
BTW, I had the same problem with swagger/OpenApi endpoint. I needed to move UseOpenApi and UseSwaggerUi3 methods before the UseAuthentication in Configure so the endpoint does not need authentication to render the ui.Marginal
@Marginal Actually, the order of services doesn't matter, which is different from middlewares :)Leannleanna
I think this a more appropriate answer as it uses the existing Middleware functionality of using the stuff in correct order..Dharna

© 2022 - 2024 — McMap. All rights reserved.