我可以避免http质询响应吗?
Can I avoid http challenge response?
我们正在使用 HttpClient 联系 REST-services,我们知道这需要 NTLM 或协商授权。
问题是 HttpClient 会首先在没有授权的情况下联系服务(那叫 challenge-response 吗?)。客户端被服务器以 401 拒绝,然后客户端才会使用授权 header.
将请求发送到服务器
我们可以通过在第一个请求上添加授权 header 来避免这种往返吗?
我们正在这样创建 http-client(问题与“NTLM”和“协商”相同):
public Rest.IRestClient Create()
{
var credentials = new CredentialCache { { _uri, "NTLM", CredentialCache.DefaultNetworkCredentials } };
#if NETCOREAPP2_2
var handler = new SocketsHttpHandler { Credentials = credentials, MaxConnectionsPerServer = 100, UseProxy = false };
#elif NET461
var handler = new WebRequestHandler { Credentials = credentials, UnsafeAuthenticatedConnectionSharing = true, MaxConnectionsPerServer = 100, UseProxy = false };
#endif
var httpClient = new HttpClient(handler) { BaseAddress = _uri, Timeout = _timeout };
httpClient.DefaultRequestHeaders.ConnectionClose = false;
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(HostMediaTypeTranslator.GetMediaType(_hostMediaType)));
if (_defaultRequestHeaders != null)
{
foreach (var header in _defaultRequestHeaders)
httpClient.DefaultRequestHeaders.Add(header.Name, header.Value);
}
ServicePointManager.FindServicePoint(_uri).ConnectionLeaseTimeout = 120 * 1000; // Close connection after two minutes
return new Rest.RestClient(httpClient, _hostMediaType);
}
是否可以只创建我们自己的 NTLM 或 Kerberos 令牌并将其作为 header 添加到 http-request?
不,因为您误解了 NTLM 的工作原理,尤其是 NTLM 握手。
来自服务器的初始 401 拒绝响应也包含 challenge/nonce。来自客户端的后续请求需要包含该质询,并使用身份验证帐户密码的哈希值进行加密。
这就是 NTLM 的工作方式,没有办法绕过它,因为您不知道(并且故意不能)知道服务器将要发送的随机数。
参考:https://docs.microsoft.com/en-gb/windows/win32/secauthn/microsoft-ntlm
我们正在使用 HttpClient 联系 REST-services,我们知道这需要 NTLM 或协商授权。
问题是 HttpClient 会首先在没有授权的情况下联系服务(那叫 challenge-response 吗?)。客户端被服务器以 401 拒绝,然后客户端才会使用授权 header.
将请求发送到服务器我们可以通过在第一个请求上添加授权 header 来避免这种往返吗?
我们正在这样创建 http-client(问题与“NTLM”和“协商”相同):
public Rest.IRestClient Create()
{
var credentials = new CredentialCache { { _uri, "NTLM", CredentialCache.DefaultNetworkCredentials } };
#if NETCOREAPP2_2
var handler = new SocketsHttpHandler { Credentials = credentials, MaxConnectionsPerServer = 100, UseProxy = false };
#elif NET461
var handler = new WebRequestHandler { Credentials = credentials, UnsafeAuthenticatedConnectionSharing = true, MaxConnectionsPerServer = 100, UseProxy = false };
#endif
var httpClient = new HttpClient(handler) { BaseAddress = _uri, Timeout = _timeout };
httpClient.DefaultRequestHeaders.ConnectionClose = false;
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(HostMediaTypeTranslator.GetMediaType(_hostMediaType)));
if (_defaultRequestHeaders != null)
{
foreach (var header in _defaultRequestHeaders)
httpClient.DefaultRequestHeaders.Add(header.Name, header.Value);
}
ServicePointManager.FindServicePoint(_uri).ConnectionLeaseTimeout = 120 * 1000; // Close connection after two minutes
return new Rest.RestClient(httpClient, _hostMediaType);
}
是否可以只创建我们自己的 NTLM 或 Kerberos 令牌并将其作为 header 添加到 http-request?
不,因为您误解了 NTLM 的工作原理,尤其是 NTLM 握手。
来自服务器的初始 401 拒绝响应也包含 challenge/nonce。来自客户端的后续请求需要包含该质询,并使用身份验证帐户密码的哈希值进行加密。
这就是 NTLM 的工作方式,没有办法绕过它,因为您不知道(并且故意不能)知道服务器将要发送的随机数。
参考:https://docs.microsoft.com/en-gb/windows/win32/secauthn/microsoft-ntlm