我有一些关于 HTTP 身份验证的基本问题

1) 客户端如何知道服务器的 HTTP 认证类型(Basic/Digest/NTLM)?这可以在 HTTP 服务器端配置吗?



2)如果我将squid linux代理放在客户端和服务器之间;我的客户端代码是否还需要了解代理的身份验证类型?还是认证类型只和端HTTP服务器有关?



3) 使用 WireShark 发现从浏览器到服务器有三个请求来完成单个请求。


WWW-Authenticate: Digest realm="realm", qop="auth", nonce="MTM1OTYyMzkyNDU4MzpiOWM0OWY0NmMzMzZlMThkMDJhMzRhYmU5NjgwNjkxYQ=="\r\n <BR>


WWW-Authenticate: Digest realm="realm", qop="auth", nonce="MTM1OTYyMzk0OTAyMTo3Njk3MDNhZTllZDQyYzQ5MGUxYzI5MWY2MGU5ZDg0Yw==", stale="true"\r\n



我的问题是第二次和第三次浏览器发送相同的请求;为什么服务器第二次失败而第三次成功。这是因为我的服务器实现吗? (我有带有 SPRING 安全过滤器的 REST Java 服务器)。

我有 C# HTTP 客户端;



为什么浏览器和 C# 客户端之间存在这种差异?



4) 现在我面临的真正问题是当 SQUID LINUX PROXY 进入我们的客户端和 HTTP 服务器之间时,浏览器执行了相同的三个请求身份验证并成功了。但是,C# HttpWebRequest 在第二次请求时失败 (401) 并到达缓存(异常){} 块并且没有第三次尝试。
当代理服务器介于两者之间时,您能否请任何人澄清我如何在 C# 客户端中解决此问题?

下面的代码正在执行 GET 请求。
  HttpWebRequest request = WebRequest.Create("url") as HttpWebRequest;
  request.Credentials = new NetworkCredential(loginUserName, password);
  WebResponse response = request.GetResponse();

请注意,我们对代理的请求是通过 TCP 协议(protocol)而不是 HTTP 协议(protocol)发送的。然后从 PROXY 到 SERVER 用 HTTP 协议(protocol)进行通信。
但是来自代理的 HTTP 请求在 HTTP header X-Forwarded-For 中包含有关我们客户端 IP 的信息。

以下是可能的解决方案

仅当您的代理需要任何身份验证时才需要这些解决方案,否则忽略它。
解决方案 1:为我工作
request.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

解决方案2:
  IWebProxy proxy = WebRequest.GetSystemWebProxy();
  proxy.Credentials = new NetworkCredential(UserName, UserPassword, UserDomain);
  request.Proxy = proxy;

Martin给出的解决方案3:
  var proxy = new WebProxy ("http://localhost:3128/");
  proxy.Credentials = new NetworkCredential (UserName, UserPassword, UserDomain);
  request.Proxy = proxy;

了解有关代理身份验证的更多信息,请访问
http://wiki.squid-cache.org/Features/Authentication

最佳答案

这是一个质询/响应协议(protocol)。通常,客户端会在没有任何身份验证 header 的情况下发出初始请求(您可以设置 request.PreAuthenticate = true 以在第一个请求中发送凭据)。

然后,服务器用它支持的身份验证方法列表进行响应。

如果用户没有使用 CredentialsCache 明确指定身份验证方法,运行时将尝试所有方法,从最强到最弱。某些协议(protocol)(例如 NTLM)需要从客户端到服务器的多个请求。理论上,Digest 应该只处理一个,不知道为什么它会发送两次请求。

关于您的代理问题,有两种不同的身份验证:

  • 目标 Web 服务器的身份验证,代理只是简单地传递它,您的客户端不需要任何特殊代码。
  • 除此之外,代理本身也可能需要身份验证——这可能与目标 Web 服务器之一不同。

  • 您指定这些使用
    var proxy = new WebProxy ("http://localhost:3128/");
    proxy.Credentials = new NetworkCredential ("username", "password");
    

    然后
    WebRequest.DefaultWebProxy = proxy;
    

    或者
    request.Proxy = proxy;
    

    如果您的代理服务器不使用任何身份验证,请不要在 WebProxy 上设置任何凭据。

    如果在使用代理服务器时无法进行身份验证,请查看使用 Wireshark 在三方(Web 服务器、代理、客户端)之间发送的实际请求。

    关于c# - HTTP 407(需要代理身份验证),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14641492/

    10-17 01:38