简体   繁体   English

使用ASP.NET的简单反向代理,带有身份验证的C#

[英]A simple reverse proxy using ASP.NET, C# with authentication

I am attempting to forward custom parameters to a RESTful API server and return the proxied response to the client-facing server. 我试图将自定义参数转发到RESTful API服务器并将代理响应返回到面向客户端的服务器。 I don't want the client to have access to or be able to read the API HTTP request/response interactions, so I decided to perform this action using a reverse proxy. 我不希望客户端有权访问或能够读取API HTTP请求/响应交互,因此我决定使用反向代理执行此操作。 I have no problem forwarding the request and returning a response. 我没有问题转发请求并返回响应。 The problem lies in the authentication. 问题在于身份验证。 The client-facing server always wants to redirect to the login page because it doesn't believe the client is authenticated. 面向客户端的服务器总是希望重定向到登录页面,因为它不相信客户端已通过身份验证。 I have tried using HTTPS and HTTP with similar results. 我尝试过使用HTTPS和HTTP,结果相似。

I have been researching this problem for quite some time and found quite a variety of answers, none of which seem to quite encompass my specific use case. 我已经研究了这个问题已经有一段时间了,并且发现了各种各样的答案,其中没有一个似乎完全涵盖了我的具体用例。 I am following this example , which is the closest to what I specifically need. 我跟随这个例子 ,这是我最接近我特别需要的。 However, the credentials portion the author commented out ( //request.Credentials = CredentialCache.DefaultCredentials; ) doesn't seem to cover the authentication portion I am attempting to implement. 但是,作者注释掉的凭证部分( //request.Credentials = CredentialCache.DefaultCredentials; )似乎不包括我试图实现的身份验证部分。 Please help me understand this problem and solution. 请帮我理解这个问题和解决方案。

Here is the code I am using from the controller: 这是我在控制器中使用的代码:

public ActionResult ProxyEndpoint(string custom_string, string another_custom_string)
{
    //Bunch of code here to grab the remoteUrl from AppConfig and do stuff to the parameters and store them in queryString, unnecessary to show here.

    //Here's the important bits:
    remoteUrl = remoteUrl + "?" + queryString; // create my remoteUrl
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(remoteUrl);
    request.Credentials = CredentialCache.DefaultCredentials;
    // Also tried this to no avail:
    request.Credentials = CredentialCache.DefaultNetworkCredentials;
    return ProxyActionResult(request.GetResponse());
}

Here is the ProxyActionResult class: 这是ProxyActionResult类:

public class ProxyActionResult : ActionResult
{
    WebResponse _response;

    public ProxyActionResult(WebResponse response)
    {
        _response = response;
    }

    public override void ExecuteResult(ControllerContext controllerContext)
    {
        HttpContextBase httpContext = controllerContext.HttpContext;
        WebResponse response = _response;

        // Read the byte stream from the response:
        Stream responseStream = response.GetResponseStream();

        // Pulled this next piece from http://www.codeproject.com/Articles/7135/Simple-HTTP-Reverse-Proxy-with-ASP-NET-and-IIS
        // Seemed to fit our use case.
        if ((response.ContentType.ToLower().IndexOf("html") >= 0) || (response.ContentType.ToLower().IndexOf("javascript") >= 0))// || (response.ContentType.ToLower().IndexOf("image") >= 0))
        {
            //If the response is HTML Content, parse it like HTML:
            StreamReader readStream = new StreamReader(responseStream, Encoding.Default);

            String content;

            content = ParseHtmlResponse(readStream.ReadToEnd(), httpContext.Request.ApplicationPath);

            //Write the updated HTML to the client(and then close the response):
            httpContext.Response.Write(content);
            httpContext.Response.ContentType = response.ContentType;

            response.Close();
            httpContext.Response.End();
        }
        else
        {
            // If the response is not HTML Content, write the stream directly to the client:
            var buffer = new byte[1024];
            int bytes = 0;
            while ((bytes = responseStream.Read(buffer, 0, 1024)) > 0)
            {
                httpContext.Response.OutputStream.Write(buffer, 0, bytes);
            }
            // from http://www.dotnetperls.com/response-binarywrite
            httpContext.Response.ContentType = response.ContentType; // Set the appropriate content type of the response stream.
            // and close the stream:
            response.Close();
            httpContext.Response.End();
        }
        //throw new NotImplementedException();
    }
    // Debating whether we need this:
    public string ParseHtmlResponse(string html, string appPath)
    {
        html = html.Replace("\"/", "\"" + appPath + "/");
        html = html.Replace("'/", "'" + appPath + "/");
        html = html.Replace("=/", "=" + appPath + "/");
        return html;
    }

It turns out that nothing is wrong with the reverse proxy code. 事实证明,反向代理代码没有任何问题。 The remote server was an ArcGIS OpenLayers API and it had a setting that said crossOrigin: anonymous . 远程服务器是ArcGIS OpenLayers API,它有一个设置,表示crossOrigin: anonymous I commented out this setting and it worked perfectly. 我评论了这个设置,它运作得很好。

Check out the documentation if you have this particular ArcGIS OpenLayers problem: http://openlayers.org/en/v3.14.2/apidoc/ol.source.ImageWMS.html 如果您有这个特定的ArcGIS OpenLayers问题,请查看文档: http//openlayers.org/en/v3.14.2/apidoc/ol.source.ImageWMS.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM