代码之家  ›  专栏  ›  技术社区  ›  Skip Saillors

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

  •  0
  • Skip Saillors  · 技术社区  · 7 年前

    我编写了ASP.NET框架MVC和Web API 2程序

    我要去休息一下了解一些情况。此服务的安全性要求的性质要求我从一组有限的已知IP地址请求。我的客户机需求的性质是有一个未知数量的IP,由一些DHCP分配。我认为我需要站起来代理,将请求转发到服务,并将响应返回到请求的客户机。这个服务器可以分配一个静态IP,我可以向目标服务注册。我不想尝试复制目标服务的签名,每当他们决定改进接口时,我就必须维护我的代理。

    我将拥有限制IP并接受GeT的服务 http://S/action 举个例子。我的代理人在 http://P/action . 客户会发送GET http://p/行动 作为回应,P会发送GET http://s/操作 ,收集响应,将其返回给客户机。

    为了实现这个策略,我为P构建了一个不起作用的处理程序:

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

    委托代理是一种让依赖项注入容器参与的方法:

    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向目标发送请求。后处理器将是一个noop。

    我没有建立任何控制器。我的想法是,如果这个管道按照我的预期运行,就不会有任何需要调用的控制器。当我发送Ant请求时, http://P/anything 返回404,而不是htto://s/anything。我错过了什么?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Steve Land    7 年前

    任何特定的原因都不只是编写一组匹配的控制器,这些控制器接受客户端请求,然后使用实现简单Web客户端的服务在第三方API上执行等效请求,然后返回响应-可能包括一些身份验证和CACH降低对API影响的逻辑?

    如果您的第三方API提供商通过IP限制请求,这可能是因为他们信任(或明确要求)您管理对其API的请求,以保护其免受过度负载和/或安全风险的影响。直接转发所有客户机请求,而不在中间件中使用任何逻辑,意味着您正在否定这一限制。

    如果 只有 您的应用程序的目的是提供一个静态IP(并且您不需要在代码中添加任何逻辑),那么您应该考虑使用许多现成的API网关产品中的一种,例如。 ,这是一个开放源代码,非常成熟,有大量社区支持 https://konghq.com/kong-community-edition/

    推荐文章