Web服务的代理Web服务-我在哪里丢失了?

时间:2018-07-19 21:44:06

标签: c# asp.net-web-api2

我编写ASP.NET Framework MVC和Web API 2

我必须访问REST服务以获取某些信息。这项服务的安全要求的性质要求我从一组有限的已知IP地址中询问。我的客户要求的性质是,其中某些IP的数量是未知的,而IP是由某些DHCP分配的。我想我需要站起来一个代理,该代理将请求转发给服务,并将响应返回给所请求的客户端。可以为该服务器分配一个静态IP,我可以在目标服务中注册该IP。我不想尝试复制目标服务的签名,而不必在他们决定改进接口时维护我的代理。

我将使用限制IP并接受http://S/action的GET作为示例的服务。我将在http://P/action获得代理。客户端将发送GET http://P/action,而P将作为响应,发送GET http://S/action,收集响应,然后将其返回给客户端。

尝试实施此策略,这是我为P建立的处理程序不起作用:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        DelegatingHandler handler = new DelegatingHandlerProxy<ProxyHandler>();
        config.MessageHandlers.Add(handler);
    }
}

DelegatingProxyHandler是一种让我的依赖项注入容器参与其中的方法:

public sealed class DelegatingHandlerProxy<THandler> : DelegatingHandler
    where THandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        IDependencyScope scope = request.GetDependencyScope();
        Task<HttpResponseMessage> task;
        if (scope.GetService(typeof(THandler)) is DelegatingHandler handler)
        {
            if (!ReferenceEquals(handler.InnerHandler, InnerHandler))
            {
                handler.InnerHandler = InnerHandler;
            }

            HttpMessageInvoker invoker = new HttpMessageInvoker(handler);
            task = invoker.SendAsync(request, cancellationToken);
        }
        else
        {
            throw new InvalidOperationException("Handler not registered with DI container");
        }

        return task;
    }
}

我要做的工作是:

public class ProxyHandler: DelegatingHandler
{
    public ProxyHandler(
        ITransformRequest preProcessor,
        ITransformResponse postProcessor,
        IForwardRequest forwarder)
    {
        PreProcessor = preProcessor;
        PostProcessor = postProcessor;
        Forwarder = forwarder;
    }

    private ITransformRequest PreProcessor { get; }
    private ITransformResponse PostProcessor { get; }
    private IForwardRequest Forwarder { get; }

    #region Overrides of DelegatingHandler

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        if (request == null)
        {
            throw new ArgumentNullException(nameof(request));
        }

        if (PreProcessor != null)
        {
            request.RequestUri = PreProcessor.Transform(request.RequestUri);
        }

        HttpResponseMessage response = await Forwarder.Forward(request, cancellationToken);
        HttpResponseMessage transformedResponse = PostProcessor.Transform(response);
        return transformedResponse;
    }

    #endregion
}

在这种情况下,DI容器提供了一个预处理器,该预处理器将请求的主机,端口和前缀更改为目标服务。转发器使用HttpClient将请求发送到目标。 PostProcessor将是noop。

我没有构建任何控制器。我的想法是,如果该管道的行为符合我的预期,则不会有任何控制器需要调用。当我向其发送蚂蚁请求时,http://P/anything返回404,而不是htto:// S / anything。我想念什么?

1 个答案:

答案 0 :(得分:0)

由于某些特殊原因,您不仅要编写一组匹配的控制器来接受客户端请求,然后使用实现简单Web客户端的服务在第3 arty API上执行等效请求,然后返回响应-可能包括一些响应身份验证和缓存逻辑来降低对其API的影响?

如果您的第三方API提供商通过IP限制请求,则可能是因为他们信任(或明确要求)您管理对其API的请求,以保护其免受过多的负载和/或安全风险。在中间件中没有任何逻辑的情况下直接转发所有客户端请求意味着您正在消除此限制。

如果应用程序的 only 目的是提供静态IP(并且您无需在代码中添加任何逻辑),则应考虑使用许多现成的API之一网关产品-例如 Kong ,这是一个开放源代码,并且在社区支持方面https://konghq.com/kong-community-edition/