内网- web到远程wcf CredentialCache.DefaultNetworkCredentials不工作
本文关键字:CredentialCache DefaultNetworkCredentials 工作 wcf web 内网 | 更新日期: 2023-09-27 18:15:16
我有一个ASP。. NET MVC内部网应用程序托管在IIS中,添加了WCF服务引用,WCF驻留在另一台计算机上,也期望windows身份验证。在我的网站上,这段代码工作得很好:
proxy = new MyProxyClient("configurationName", "remoteAddress");
proxy.ClientCredentials.Windows.ClientCredential.UserName = "myUserName";
proxy.ClientCredentials.Windows.ClientCredential.Password = "MyPassword";
proxy.SomeMethod(); //work great
但是如果我想要凭证不像这样硬编码,我使用:CredentialCache。DefaultNetworkCredentials如下:
proxy = new MyProxyClient("configurationName", "remoteAddress");
proxy.ClientCredentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
proxy.SomeMethod(); //not working throw exception
上面的代码抛出SecurityNegotiationException并伴有消息:调用者未通过服务进行身份验证。安全令牌请求不能被满足,因为身份验证失败。
如何在不硬编码用户名和密码的情况下将当前用户的凭据传递给WCF服务?
如果你的组织使用常规的Windows身份验证(NTLM),你不能做你想做的,因为"一跳"限制:凭据从用户的计算机传递到你的服务器使用"一跳"(从直接登录到一台外部计算机),这样的凭据不能用于从第一个服务器认证其他服务器。
可以使用以下搜索词找到更多信息:ntlm一跳,即。为什么NTLM失败而Kerberos可以工作。
标准解决方案:- Kerberos(通常需要付出很大的努力才能获得启用/配置的批准)
- 使用其他形式的身份验证而不是Windows。考虑OAuth是否可行。不要使用基本授权。
- 将WCF服务切换为基于声明的身份验证 如果WCF服务可以信任调用者来验证传入的凭据,那么更多的方法是可能的:
- 在服务器本地登录并具有调用服务权限的特定帐户下运行代码。最简单的方法是在你的帖子中显示的,但是以明文形式存储域密码(或任何密码)是不安全的。还可以在访问远程服务的特殊凭据下运行进程帐户,并在验证用户凭据后临时恢复模拟。
- 您还可以配置WCF服务要求客户端证书,并在调用WCF服务时使用该证书。这样WCF服务可以验证调用者是否已知。
在网上。配置(客户端和服务器),在<system.serviceModel>
部分添加/修改绑定,如下所示:
<basicHttpBinding>
<binding name="MyBasicBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
并将其添加到客户端web。配置<system.web>
section:
<identity impersonate="true" />
<authentication mode="Windows" />
这两个更改将使最终用户成为web请求的当前用户,然后该请求将在WCF消息中发送。
然后可以在服务器端像这样检索用户:ServiceSecurityContext.Current.WindowsIdentity
请确保在service web.config中有以下配置。
<system.serviceModel>
<services>
<service name="MyWcf.Service1" behaviorConfiguration="MySvcBehavior">
<endpoint address="" binding="wsHttpBinding" contract="MyWcf.IService1" bindingConfiguration="MyWsHttpBinding"></endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="MyWsHttpBinding">
<security mode="Message">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
<basicHttpBinding>
<binding name="MyBasicBinding">
<security mode="Message">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MySvcBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
在您的客户端配置文件中应该有以下内容。
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security>
<transport clientCredentialType="Windows" />
<message clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/MyWcf/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="MyWCFService.IService1"
name="WSHttpBinding_IService1">
</endpoint>
</client>
</system.serviceModel>
我尝试通过使用上面的配置和System.Net.CredentialCache.DefaultNetworkCredentials
为我工作。如果它不适合你,然后把调试点在线传递凭证,并观察System.Net.CredentialCache.DefaultNetworkCredentials
域,用户名&密码值为空或不为空。
我假设如果您正在查看CredentialCache.DefaultNetworkCredentials
属性,则不会看到凭据信息。来自Microsoft网站:DefaultNetworkCredentials属性返回的身份验证信息将仅适用于NTLM、Negotiate或Kerberos身份验证。
要获得您的凭据,您需要实现此身份验证。
可以通过在内部网应用程序中使用模拟来使用它。模拟允许内部网应用程序由该应用程序的用户执行。
更多信息在这里:http://technet.microsoft.com/en-us/library/cc961980.aspx