Search code examples
c#asp.net-coremiddlewareasp.net-core-middlewarehealth-check

Is it possible to protect HealthCheck endpoints other than Authorization in ASP.NET Core?


The case I'm trying to handle is protecting the health endpoint generated by using IEndpointRouteBuilder.MapHealthChecks not via authorization, but by some other mechanism.

My first thought was to add an IActionFilter, but I don't see how that's possible. I tried adding the attribute as metadata with a call to IEndpointConventionBuilder.WithMetadata but it seems like unless it's implemented to make use of those attributes, it'll just ignore them.

As such, my best solution right now was to do the following:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health").Add(endpointBuilder =>
    {
        RequestDelegate next = endpointBuilder.RequestDelegate!;
        endpointBuilder.RequestDelegate = async context =>
        {
            bool success = true;
            
            // Do your custom logic here.

            if (success)
            {
                await next();
            }
            else
            {
                // Do I need to set some headers here as well?
                context.Response.StatusCode = 400;
                await context.Response.CompleteAsync();
            }
            
        };
    });

    endpoints.MapControllers();
});

Using the above Add method, I'm able to chain my logic like that, but it feels hacky. Is there really no other alternative to adding filters to the generated /health endpoint above?

The reason I don't want to use a policy, is because the application doesn't even have authorization/authentication enabled. In order to import my logic into a policy, I'd have to register an authentication scheme, which seems dirty, granted I won't even be using it.


Solution

  • This approach you're taking looks reasonable. In .NET 7 you'll be able to add filters that can run before endpoints like this. We'd generally recommend integrating with the auth system but I can understand just wanting to write a function that returns a bool :).