内网- 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服务?

内网- web到远程wcf CredentialCache.DefaultNetworkCredentials不工作

如果你的组织使用常规的Windows身份验证(NTLM),你不能做你想做的,因为"一跳"限制:凭据从用户的计算机传递到你的服务器使用"一跳"(从直接登录到一台外部计算机),这样的凭据不能用于从第一个服务器认证其他服务器。

可以使用以下搜索词找到更多信息:ntlm一跳,即。为什么NTLM失败而Kerberos可以工作。

标准解决方案:

  • Kerberos(通常需要付出很大的努力才能获得启用/配置的批准)
  • 使用其他形式的身份验证而不是Windows。考虑OAuth是否可行。不要使用基本授权。
  • 将WCF服务切换为基于声明的身份验证
  • 如果WCF服务可以信任调用者来验证传入的凭据,那么更多的方法是可能的:
    1. 在服务器本地登录并具有调用服务权限的特定帐户下运行代码。最简单的方法是在你的帖子中显示的,但是以明文形式存储域密码(或任何密码)是不安全的。还可以在访问远程服务的特殊凭据下运行进程帐户,并在验证用户凭据后临时恢复模拟。
    2. 您还可以配置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