我有一个在IIS中托管的ASP.NET MVC Intranet应用程序,它添加了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服务?
答案 0 :(得分:3)
如果您的组织使用常规Windows身份验证(NTLM),由于“一跳”限制,您无法执行所需操作:从用户计算机传递到服务器的凭据使用“一跳”(从直接登录到一个)外部计算机)并且此类凭据不能用于验证第一个服务器中的其他服务器。
使用以下搜索词可以找到更多信息:ntlm one hop,即。 Why NTLM fails and Kerberos works
标准解决方案:
答案 1 :(得分:0)
在web.config(客户端和服务器)中,在<system.serviceModel>
部分添加/修改绑定,看起来像这样:
<basicHttpBinding>
<binding name="MyBasicBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
并将此添加到客户端web.config <system.web>
部分:
<identity impersonate="true" />
<authentication mode="Windows" />
这两项更改将使最终用户成为Web请求的当前用户,然后将在WCF消息中发送。
然后可以在服务器端检索用户,如下所示:
ServiceSecurityContext.Current.WindowsIdentity
请确保服务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
域,用户名和&amp;密码值为空或不是。如果是空白则应该有效。
答案 2 :(得分:-1)
我认为,如果您在CredentialCache.DefaultNetworkCredentials
attribut内查看,则不会看到凭据信息。
来自Microsoft网站:DefaultNetworkCredentials属性返回的身份验证信息仅适用于NTLM,Negotiate或Kerberos身份验证。
要获取凭据,您需要实施此身份验证。
您可以通过内部网应用程序使用模拟来使用它。 模拟允许您的Intranet应用程序由此用户执行。
此处提供更多信息:http://technet.microsoft.com/en-us/library/cc961980.aspx