Apache NTLM Auth from C# client do not work with s

2019-05-25 06:28发布

问题:

I have a office plugin that connect a service using HttpWebRequest.

Inside a domain I pass CredentialCache.DefaultNetworkCredentials so all is fine. Outside a domain a user need to provide username, domain and password. This don't work atm.

Some part of the code out of it:

CookieContainer cookies = new CookieContainer();

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Post;
request.AllowAutoRedirect = true;
request.CookieContainer = cookies; // provide session cookie to handle redirects of login controller of the webservice

if (isWindowAuthentication) // isWindowAuthentication is set earlier by config
{
  if (Common.UserName.Length > 0)
  {
    string[] domainuser;
    string username;
    string domain;

    if (Common.UserName.Contains("@"))
    {
      domainuser = Common.UserName.Split('@');
      username = domainuser[0];
      domain = domainuser[1];
    }
    else
    {
      domainuser = Common.UserName.Split('\\');
      username = domainuser[1];
      domain = domainuser[0];
    }
    NetworkCredential nc = new NetworkCredential(username, Common.Password, domain);
    CredentialCache cache = new CredentialCache();
    cache.Add(request.RequestUri, "NTLM", nc);
    request.Credentials = cache;
  }
  else
  {
    request.Credentials = CredentialCache.DefaultNetworkCredentials;
  }
}

Later on I do the request request.GetResponse();. If I use CredentialCache.DefaultNetworkCredentials then everything works fine. The moment I switch to my own new NetworkCredential() part the authentication fails.

I checked the logs of the Apache (it is Apache 2.2 using SSPI mod). When it succeed the first request redirect to the login controller, then the login controller request credentials. Passed and works (redirect to the target site).

Log 1 (works):

192.168.14.9 - - [25/Oct/2012:11:35:35 +0200] "POST /ror/ioi/start?document%5Bguid%5D=%7Be3d8f1de-10f2-4493-a0c0-97c2acb034e6%7D HTTP/1.1" 302 202
192.168.14.9 - - [25/Oct/2012:11:35:35 +0200] "GET /ror_auth/login?ror_referer=%2Fror%2Fioi%2Fstart%3Fdocument%255Bguid%255D%3D%257Be3d8f1de-10f2-4493-a0c0-97c2acb034e6%257D HTTP/1.1" 401 401
192.168.14.9 - - [25/Oct/2012:11:35:35 +0200] "GET /ror_auth/login?ror_referer=%2Fror%2Fioi%2Fstart%3Fdocument%255Bguid%255D%3D%257Be3d8f1de-10f2-4493-a0c0-97c2acb034e6%257D HTTP/1.1" 401 401
192.168.14.9 - rausch [25/Oct/2012:11:35:35 +0200] "GET /ror_auth/login?ror_referer=%2Fror%2Fioi%2Fstart%3Fdocument%255Bguid%255D%3D%257Be3d8f1de-10f2-4493-a0c0-97c2acb034e6%257D HTTP/1.1" 302 156

The own credential results here Log 2 (do not work):

192.168.14.9 - - [25/Oct/2012:12:05:23 +0200] "POST /ror/ioi/start?document%5Bguid%5D=%7B6ac54e8a-19f1-4ccd-9684-8d864dd9ccf7%7D HTTP/1.1" 302 202
192.168.14.9 - - [25/Oct/2012:12:05:23 +0200] "GET /ror_auth/login?ror_referer=%2Fror%2Fioi%2Fstart%3Fdocument%255Bguid%255D%3D%257B6ac54e8a-19f1-4ccd-9684-8d864dd9ccf7%257D HTTP/1.1" 401 401

What I don't understand is when I inspect e.g. CredentialCache.DefaultNetworkCredentials.UserName then is is empty.

Anyone know what to do and how I have to set my own credentials correct that the authentication works as expected?

回答1:

Finally after a lot of testing and investigation and many resources on stack overflow I found out what is going on.

The problem seems to be that the httpwebrequest don't handle the authentication when parts of the webseite requests credentials and some don't.

Background:

Our Site has its own session management and redirect to a login controller when no valid session is available. Only this login controller is set to NTLM authentication.

This we made because we have a web site without NTLM auth at all (no 401, 302 request loops in IE!) and only validate once (and we handle authentication on different url to prevent the problem that IE stop posting data at non-authenticated sites => see http://support.microsoft.com/?id=251404).

Solution:

I normally sent a request on my target page and the webserver redirect, authenticate and redirect back to the target. As the httpwebrequest don't handle this for any reason if I have my own credentials set (see above code of my question) I changed to code to authenticate once to my login controller and store the session in a cookie container.

For all following request I don't autenticate at all anymore. I add the cookie container and my server gets a valid session. So I don't have to authenticate anymore. Sideeffect is better performance this way.

Another tricky thing was that I not only use httpwebrequest, I also use a webform control. Therefor I found the solution to add my own cookie session here: Use cookies from CookieContainer in WebBrowser (Thanks to Aaron who saved me a lot of trouble as well).