如何在 ASP.NET Core 健康检查调用 (MapHealthChecks) 中检查用户代理?

Vek*_*ksi 2 asp.net-core

https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check指出

大型企业开发团队通常需要遵守公开 API 的安全要求。为了保护运行状况检查端点,您应该首先使用 IP 限制、客户端证书或虚拟网络等功能来限制应用程序访问。您可以通过要求传入请求的用户代理与 ReadyForRequest/1.0 匹配来保护运行状况检查端点。用户代理无法被欺骗,因为该请求已经受到先前安全功能的保护。

在实践中如何检查用户代理?我在想代码

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapHealthChecks("/health", new HealthCheckOptions { AllowCachingResponses = false });
});
Run Code Online (Sandbox Code Playgroud)

然后在 Azure 中,WebApp 会在回复之前检查它是来自 Azure 服务的呼叫,而不是来自公共 Internet 的呼叫(否则直接挂断呼叫)。不过,我知道有更好的方法可以在边缘做到这一点。

我的想法是,我想到的选项是编写一个中间件组件来检查 URL 和代理。虽然也许我错过了一些明显的事情,但这不是方法?:)

Ale*_*der 5

您可以创建执行用户代理要求验证的策略

public class UserAgentRequirement : IAuthorizationRequirement
{
    public string UserAgent { get; }

    public UserAgentRequirement(string userAgent)
    {
        UserAgent = userAgent;
    }
}

public class UserAgentAuthorizationHandler : AuthorizationHandler<UserAgentRequirement>
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public UserAgentAuthorizationHandler(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserAgentRequirement requirement)
    {
        var httpContext = httpContextAccessor.HttpContext;
        
        var agent = httpContext.Request.Headers["User-Agent"];
        if (agent == requirement.UserAgent)
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
        return Task.CompletedTask;
    }
}
Run Code Online (Sandbox Code Playgroud)

不要忘记注册IHttpContextAccessorUserAgentAuthorizationHandler。在Startup.cs中

services.AddHttpContextAccessor();
services.AddScoped<IAuthorizationHandler, UserAgentAuthorizationHandler>();

services.AddAuthorization(options =>
{
    //...
    options.AddPolicy("HealthCheckPolicy", builder =>
    {
        builder.AddRequirements(new UserAgentRequirement("ReadyForRequest/1.0"));
    });
});

//...

app.UseEndpoints(endpoints =>
{
    endpoints
        .MapHealthChecks("/health", new HealthCheckOptions { AllowCachingResponses = false })
        .RequireAuthorization("HealthCheckPolicy");
    //...
});
Run Code Online (Sandbox Code Playgroud)