我有一些关于 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 应该只处理一个,不知道为什么它会发送两次请求。
关于您的代理问题,有两种不同的身份验证:
您指定这些使用
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/