WCF 客户端缓存 Windows 身份验证

Posted

技术标签:

【中文标题】WCF 客户端缓存 Windows 身份验证【英文标题】:WCF client caching windows authentication 【发布时间】:2012-08-01 08:56:20 【问题描述】:

我正在调用由 Navision 公开的 Web 服务,它通过 Windows 身份验证进行保护。我能够成功调用它,但在那之后,它似乎正在以某种方式缓存凭据,这让我很担心。

该服务托管在远程服务器上,并且与我的开发机器位于不同的域中。我正在从 Visual Studio 运行代码。

我已经创建了对服务的服务引用,并且我的 app.config 中没有配置,所以所有设置都是使用代码创建的。

首次运行(未指定客户端凭据):

var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

var address = new EndpointAddress("http://externalserver.com/DynamicsNAV/WS/Customer/Page/MyPage");

var client = new MyPage_PortClient(binding, address);
client.ClientCredentials.Windows.AllowNtlm = true;
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

var reqObj = new MyPage()  TypeID = "Test", Company_Name = "Test:" + DateTime.Now.ToShortTimeString() ;
client.Create(ref reqObj);
client.Close();
Console.WriteLine(reqObj.Company_Name);
Console.ReadLine();

这给了我一个安全异常。正如预期的那样。

第二次运行(使用凭据):

var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

var address = new EndpointAddress("http://externalserver.com/DynamicsNAV/WS/Customer/Page/MyPage");

var client = new MyPage_PortClient(binding, address);
client.ClientCredentials.Windows.ClientCredential.Domain = "MYDOM";
client.ClientCredentials.Windows.ClientCredential.UserName = "NavWebService";
client.ClientCredentials.Windows.ClientCredential.Password = "foo";
client.ClientCredentials.Windows.AllowNtlm = true;
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

var reqObj = new MyPage()  TypeID = "Test", Company_Name = "Test:" + DateTime.Now.ToShortTimeString() ;
client.Create(ref reqObj);
client.Close();
Console.WriteLine(reqObj.Company_Name);
Console.ReadLine();

此调用成功。再次,正如预期的那样。

第三轮,和第一轮一样。也就是说,没有指定凭据。那个调用成功了。现在我很困惑。必须以某种方式缓存凭据?我重新启动机器,结果相同。还是成功了。

然后我尝试指定伪造的凭据:

var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

var address = new EndpointAddress("http://externalserver.com/DynamicsNAV/WS/Customer/Page/MyPage");

var client = new MyPage_PortClient(binding, address);
client.ClientCredentials.Windows.ClientCredential.Domain = "fakeMYDOM";
client.ClientCredentials.Windows.ClientCredential.UserName = "fakeNavWebService";
client.ClientCredentials.Windows.ClientCredential.Password = "badPwd";
client.ClientCredentials.Windows.AllowNtlm = true;
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

var reqObj = new MyPage()  TypeID = "Test", Company_Name = "Test:" + DateTime.Now.ToShortTimeString() ;
client.Create(ref reqObj);
client.Close();
Console.WriteLine(reqObj.Company_Name);
Console.ReadLine();

此调用失败。正如预期的那样。

我再次回到第一个呼叫,仍然成功。所以它实际上仍在缓存第一次成功调用的凭据,即使我同时尝试使用无效凭据。

谁能告诉我这里发生了什么?这是我对 Windows 身份验证不了解的地方吗? Visual Studio/WCF 中是否有某种凭据缓存?

【问题讨论】:

【参考方案1】:

你是对的,Windows 令牌正在被缓存。这是Impersonation and Delecation with WCF 上的一篇 MSDN 文章,其中涵盖了缓存令牌模拟。

【讨论】:

以上是关于WCF 客户端缓存 Windows 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

无法从 C# 中的客户端(控制台应用程序)从 WCF 服务(已通过 Windows 身份验证)访问 SQL Server

WCF 和自定义身份验证(用户名/密码)

“此服务的安全设置需要 Windows 身份验证”客户端证书 WCF 项目的 IIS 错误

使用 Windows 身份验证的 IIS 托管 WCF 服务和 SQL 查询

在 WCF 和 Windows 身份验证中处理 CORS

使用 WCF 的身份验证服务