来自C#客户端的Apache NTLM Auth不能与自定义的NetworkCredentials一起使用

我有一个办公室插件,使用HttpWebRequest连接服务。

在域内我通过CredentialCache.DefaultNetworkCredentials所以一切都很好。 在域外,用户需要提供用户名,域和密码。 这不起作用。

代码的某些部分:

 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; } } 

后来我做了请求请求request.GetResponse(); 。 如果我使用CredentialCache.DefaultNetworkCredentials那么一切正常。 当我切换到我自己的new NetworkCredential()部分时,身份validation失败。

我检查了Apache的日志(它是使用SSPI mod的Apache 2.2)。 成功后,第一个请求重定向到登录控制器,然后登录控制器请求凭据。 通过并工作(重定向到目标站点)。

记录1(工作):

 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 

这里自己的凭证结果是Log 2(不起作用):

 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 

我不明白的是当我检查例如CredentialCache.DefaultNetworkCredentials.UserName它是空的。

任何人都知道该怎么做以及如何设置我自己的凭据,以确保认证按预期工作?

经过大量的测试和调查以及堆栈溢出的许多资源后,我发现了发生了什么。

问题似乎是当webseite的部分请求凭据而某些部分没有请求凭证时,httpwebrequest不处理身份validation。

背景:

我们的站点有自己的会话管理,并在没有有效会话时重定向到登录控制器。 只有此登录控制器设置为NTLM身份validation。

这是因为我们有一个没有NTLM auth的网站(IE中没有401,302个请求循环!)并且只validation一次(我们处理不同URL上的身份validation以防止IE停止在未经过身份validation的情况下发布数据的问题sites =>请参阅http://support.microsoft.com/?id=251404 )。

解:

我通常在目标页面上发送请求,并且Web服务器重定向,进行身份validation并重定向回目标。 由于httpwebrequest由于任何原因而无法处理此问题,如果我拥有自己的凭据集(请参阅我的问题的上述代码),我更改为代码以对登录控制器进行一次身份validation并将会话存储在cookie容器中。

对于以下所有要求,我根本不再进行认证。 我添加了cookie容器,我的服务器获得了有效的会话。 所以我不必再进行身份validation了。 Sideeffect以这种方式表现更好。

另一个棘手的问题是我不仅使用httpwebrequest,还使用了webform控件。 因此,我在这里找到了添加我自己的cookie会话的解决方案: 在WebBrowser中使用来自CookieContainer的cookie (感谢Aaron也为我节省了很多麻烦)。