如何在标准 .Net Web API 中对 Prometheus mapPath 使用 ActionFilter?

How to use ActionFilter on Prometheus mapPath in standard .Net Web API?

我想过滤可以路由到 Prometheus 指标的客户端 IP 范围。 所以在启动时我有

    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);            
        app.UsePrometheusServer(q =>
        {
            q.MapPath = "/metrics";
        });
        app.UseWebApi(config);
    }

这是我的自定义 actionFilter class

public class IpFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext actionContext)
    {            
        string clinetIP = GetClientIpAddress(actionContext.HttpContext.Items["MS_HttpRequestMessage"] as HttpRequestMessage);
        if (IpAllowed(clinetIP))  
            base.OnActionExecuting(actionContext);
    }       

但我不知道如何使用 IpFilter,因为它不能用作控制器操作的属性。 我尝试通过使用 owin 添加中间件来使用它,但 next.Invoke 无法正常工作

    public void Configuration(IAppBuilder app)
    {     
        app.Map("/metrics", metricsApp =>
        {             
           metricsApp.Use<TestIpMid>(deniedIps);
           metricsApp.UsePrometheusServer(q => q.MapPath = "/metrics");              
        });
        app.UsePrometheusServer(q =>
        {
            q.MapPath = "/metrics";
        });
        app.UseWebApi(config);
    }

这是中间件:

    public class TestIpMid : OwinMiddleware
{
    private readonly HashSet<string> _deniedIps;

    public TestIpMid(OwinMiddleware next, HashSet<string> deniedIps) : base(next)
    {
        _deniedIps = deniedIps;
    }

    public override async Task Invoke(IOwinContext context)
    {
        var ipAddress = context.Request.RemoteIpAddress;
        if (_deniedIps.Contains(ipAddress))
        {
            context.Response.StatusCode = 403;
            return;
        }           
        await Next.Invoke(context);            
    }
}

请帮助我:'(

这个解决方案对我有用,但我想到的其他方法都不起作用

    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);

        var config = new HttpConfiguration();
        var allowedIps = ProtectedSettings.Read(ProtectedSettings.protheusIpWhitelist).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);             
        app.Use(async (Context, next) =>
        {
            var ipAddress = Context.Request.RemoteIpAddress;
            if ((!allowedIps.Contains(ipAddress)) && Context.Request.Path.Value == "/metrics")
            {
                Context.Response.StatusCode = 403;
                return;
            }
            await next.Invoke();
        });
        app.UsePrometheusServer(q =>
        {
            q.MapPath = "/metrics";

        });
        app.UseWebApi(config);
    }