According to MSDN, when HttpWebRequest.AllowAutoRedirect
property is true, redirects will clear authentication headers. The workaround given is to implement IAuthenticationModule to handle authentication:
The Authorization header is cleared on auto-redirects and HttpWebRequest automatically tries to re-authenticate to the redirected location. In practice, this means that an application can't put custom authentication information into the Authorization header if it is possible to encounter redirection. Instead, the application must implement and register a custom authentication module. The System.Net.AuthenticationManager and related class are used to implement a custom authentication module. The AuthenticationManager.Register method registers a custom authentication module.
I created a basic implementation of this interface:
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))))));
}
}
and a simple driver to exercise the functionality:
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();
}
}
When I make a request that doesn't redirect, the Authenticate
method on my class is called, and authentication succeeds. When I make a request that reutrns a 307 (temporary redirect) response, no methods of my class are called, and authentication fails. What's going on here?
I'd rather not disable auto redirect and write custom logic to handle 3xx responses myself. How can I get my authentication logic to work with auto redirect?
In place of the NetworkCredential, you should pass a CredentialCache for the request.Credentials.
According to the MSDN documentation:
I hope following would be another option that i took from code project url http://www.codeproject.com/Articles/49243/Handling-Cookies-with-Redirects-and-HttpWebRequest
Even though the OP is very old, I would nominate Crater's response as THE ANSWER. I went through similar gyrations, including creating a custom authentication module even though the web resource I was accessing only used Basic authentication. What I found was that only after I used a CredentialCache, instead of a simple NetworkCredential, did my authentication module get called after the redirect.
Furthermore, I found that since the authentication I needed was Basic, by merely supplying the CredentialCache I did not need the custom authentication module at all -- the standard Basic module worked just fine.
The following resource seemed to confirm this (in contrast to the .NET documentation reference mentioned in the OP):
https://blogs.msdn.microsoft.com/ncl/2009/05/05/custom-http-authentication-schemes/
What you need to do is likely a
POST
request. You are posting variables to authenticate, thus you need to use thePOST
action.See this post for more information: Login to website, via C#
Auto redirect shouldn't get in the way of this post request. I'd recommend installing Fiddler and logging in manually, and then watching what happens.
*Keep in mind, when sending a
POST
request, if there is a login form, you are sending thePOST
request to theaction='/some-url-or-whatever.php'
tag in the form.POST
the data to that, and you should be able to log in just fine.Let me know if this helps.