【问题标题】:Passing Windows Authentication to Proxy using HttpClient使用 HttpClient 将 Windows 身份验证传递给代理
【发布时间】:2019-11-27 04:33:52
【问题描述】:

我正在尝试将 Windows 身份验证传递给 WebProxy,这样用户就不必手动输入他的登录数据。 用例是一个代理服务器,它根据 LDAP/AD 服务器检查身份验证,而用户必须定期更改密码。

我有以下代码:

private void button1_ClickAsync(object sender, EventArgs e) {
    Url = "http://local.adress/test";
    Execute();
}

private void button2_Click(object sender, EventArgs e) {
    Url = "https://maps.googleapis.com/maps/api/timezone/json";
    Execute();
}

private void Execute() {
    var handler = new HttpClientHandler();
    handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
    handler.UseDefaultCredentials = true;
    handler.UseProxy = true;
    handler.Proxy = WebRequest.DefaultWebProxy;
    handler.Proxy.Credentials = new NetworkCredential("mydomainuser", "mydomainpassword");
    //handler.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;

    var client = new HttpClient(handler);
    Task<string> response = TestConnection(client, Url);
}

private async Task<string> TestConnection(HttpClient client, string url) {
    try {
        using (HttpResponseMessage result = await client.GetAsync(url)) {
            string res = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
            Console.WriteLine("content: " + res);
            return result.ToString();
        }
    } catch (Exception e) {
        Console.WriteLine("error: " + e.Message);
        return e.ToString();
    }
}

手动定义凭据时(如您在 Execute 方法中所见),一切都按预期工作。我检查了代理日志文件以确保请求确实通过代理转发。

由于我的目标是让用户不必输入他可能会定期更改的密码,因此我尝试通过CredentialCache.DefaultNetworkCredentials 传递凭据(我也尝试过CredentialCache.DefaultCredentials)。执行请求时,代理会记录 DENIED,我的客户端返回 HTTP 错误代码 407。

我是否遗漏了一些明显的东西?我知道关于这个话题有无数的问题,但似乎没有什么能解决这个问题。

【问题讨论】:

  • 这是 Web 应用程序还是客户端应用程序?如果是托管在 IIS 上的 Web 应用程序,应用程序池在哪个用户下运行?
  • 这是一个在Windows 10下运行WinForms的客户端应用程序,不涉及IIS。
  • 你的代理支持吗?隐式 Windows 凭据 (DefaultNetworkCredentials) 不是用户 + 密码。
  • 凭据代表用户,但这并不意味着它们带有登录名或密码。一些凭据确实包含这些,但其他凭据不包含。看看这个:如果你想使用 Windows 身份验证,你的代理必须支持它。
  • 谢谢,但我真的没有做太多 :-),事实上 如果你找到了让它工作的方法或找到解决方法,你只需回答自己

标签: c# proxy windows-authentication dotnet-httpclient


【解决方案1】:

您必须在代码中定义代理和主 URL。

var TARGETURL = "http://en.wikipedia.org/";

HttpClientHandler handler = new HttpClientHandler()
{
    Proxy = new WebProxy("http://127.0.0.1:8888"),
    UseProxy = true,
};

试试这个。

handler.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
handler.Credentials = CredentialCache.DefaultNetworkCredentials;

好的,所以您的网络服务使用 Windows 身份验证。 您的桌面客户端正在您的凭据下工作,您需要模拟 https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.impersonate?view=netframework-4.8

如果它是基本身份验证,请检查它是否适合您。

HttpClient client = new HttpClient(handler);

            **var byteArray = Encoding.ASCII.GetBytes("username:password1234");**


**client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));**

【讨论】:

  • 两个选项 Proxy = new WebProxy("http://127.0.0.1:8888")handler.Proxy = WebRequest.DefaultWebProxy; 在手动定义凭据时都有效,就像您在上面的示例中看到的那样。我已经检查了代理日志文件以确认这一点。使用CredentialCache.DefaultNetworkCredentials 时不会,但我想要它。我认为问题是在设置凭据时出现的。
  • 检查您的应用程序池身份尝试将凭据更改为新帐户。您也可以在 web.config 中放置凭据。在我的情况下 Proxy = new WebProxy("127.0.0.1:8888") 工作 handler.Proxy = WebRequest.DefaultWebProxy; 不起作用。
  • 尝试 handler.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials; handler.Credentials = CredentialCache.DefaultNetworkCredentials;
  • 不涉及 IIS。如问题中所述,我尝试通过 Windows 身份验证凭据。
  • 如果你想运行桌面客户端你必须使用模拟docs.microsoft.com/en-us/dotnet/api/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
相关资源
最近更新 更多