Keeping HTTP Basic Authentification alive while be

2019-02-18 11:47发布

问题:

We are using web service with basic authentication. It all worked all fine, till owners of web service implemented balancing service. Which is simply redirects requests to different instances of web service.

The problem is that after being redirected basic authentication fails. There is "request authentication credentials was not passed" exception.

Additional info:

  1. We have to create request manually.

        var req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(Settings.Default.HpsmServiceAddress));
    
        req.Headers.Add("Authorization", "Basic aaaaaaaaaaa");
        req.PreAuthenticate = true;
        req.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
        req.UserAgent = "Apache-HttpClient/4.1.1 (java 1.5)";
        req.KeepAlive = false;
    
        ServicePointManager.Expect100Continue = false;
    
        req.ContentType = "text/xml; charset=utf-8";
        req.Method = "POST";
        req.Accept = "gzip,deflate";
        req.Headers.Add("SOAPAction", actionName);
        byte[] buffer = Encoding.UTF8.GetBytes(envelop);
        Stream stm = req.GetRequestStream();
        stm.Write(buffer, 0, buffer.Length);
        stm.Close();
    
        WebResponse response = req.GetResponse();
        string strResponse = new StreamReader(response.GetResponseStream()).ReadToEnd();
        response.Dispose();
    
  2. We are redirected with HTTP 307 redirect

回答1:

Follow the MSDN for HttpWebRequest.AllowAutoRedirect Property i found this :

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.

Solution is to write a custom Authentication Module.

Here what i've found about it :

http://msdn.microsoft.com/en-us/library/system.net.authenticationmanager.aspx

And here the AllowAutoRedirect properties page :

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowautoredirect.aspx

UPDATE

Can you try to use CredentialCache instead of add header to webrequest ?

CredentialCache myCache = new CredentialCache();

myCache.Add(
new Uri("http://www.contoso.com/"),"Basic",new NetworkCredential(UserName,SecurelyStoredPassword));
req.Credentials = myCache;


回答2:

Indeed, CredentialCache is working correctly. However, if you would like to add multiple basic auth credentials (for example if there is redirection that you are aware of) you can use following function that I have made:

private void SetNetworkCredential(Uri uriPrefix, string authType, NetworkCredential credential)
{
    if (request.Credentials == null)
    {
        request.Credentials = new CredentialCache();
    }

    if (request.Credentials.GetCredential(uriPrefix, authType) == null)
    {
        (request.Credentials as CredentialCache).Add(uriPrefix, authType, credential);
    }
}

I hope it will help somebody in the future.