根据MSDN,当HttpWebRequest.AllowAutoRedirect
属性为 true 时,重定向将清除身份验证标头。给出的解决方法是实现 IAuthenticationModule 来处理身份验证:
Authorization 标头在自动重定向时被清除,并且 HttpWebRequest 自动尝试重新验证到重定向的位置。实际上,这意味着如果可能遇到重定向,应用程序不能将自定义身份验证信息放入 Authorization 标头中。相反,应用程序必须实现并注册一个自定义身份验证模块。System.Net.AuthenticationManager 和相关类用于实现自定义身份验证模块。AuthenticationManager.Register 方法注册一个自定义身份验证模块。
我创建了这个接口的基本实现:
public class CustomBasic : IAuthenticationModule
{
public CustomBasic() { }
public string AuthenticationType { get { return "Basic"; } }
public bool CanPreAuthenticate { get { return true; } }
private bool checkChallenge(string challenge, string domain)
{
if (challenge.IndexOf("Basic", StringComparison.InvariantCultureIgnoreCase) == -1) { return false; }
if (!string.IsNullOrEmpty(domain) && challenge.IndexOf(domain, StringComparison.InvariantCultureIgnoreCase) == -1) { return false; }
return true;
}
public Authorization PreAuthenticate(WebRequest request, ICredentials credentials)
{
return authenticate(request, credentials);
}
public Authorization Authenticate(String challenge, WebRequest request, ICredentials credentials)
{
if (!checkChallenge(challenge, string.Empty)) { return null; }
return this.authenticate(request, credentials);
}
private Authorization authenticate(WebRequest webRequest, ICredentials credentials)
{
NetworkCredential requestCredentials = credentials.GetCredential(webRequest.RequestUri, this.AuthenticationType);
return (new Authorization(string.Format("{0} {1}", this.AuthenticationType, Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", requestCredentials.UserName, requestCredentials.Password))))));
}
}
和一个简单的驱动程序来行使功能:
public class Program
{
static void Main(string[] args)
{
// replaces the existing handler for Basic authentication
AuthenticationManager.Register(new CustomBasic());
// make a request that requires authentication
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"https://www.SomeUrlThatRequiresAuthentication.com");
request.Method = "GET";
request.KeepAlive = false;
request.ContentType = "text/plain";
request.AllowAutoRedirect = true;
request.Credentials = new NetworkCredential("userName", "password");
HttpWebResponse result = (HttpWebResponse)request.GetResponse();
}
}
当我发出不重定向的请求时,Authenticate
我的类上的方法被调用,并且身份验证成功。当我发出一个重新发送 307(临时重定向)响应的请求时,我的类的任何方法都不会被调用,并且身份验证失败。这里发生了什么?
我宁愿不禁用自动重定向并编写自定义逻辑来自己处理 3xx 响应。如何让我的身份验证逻辑与自动重定向一起使用?