在正在升级的项目中,我必须在我的WCF服务中使用由第三方(无控制)发布的WCF服务(服务A )。 我一直在My Web App项目中使用 ServiceA (vs2008),它一直运行良好。
我首先在我的WCF项目中添加服务参考( ServiceB )。假设服务名称是“XYZ”。 VS创建了所有必需的文件但是当我尝试编译时它给出了错误
“ServiceB.ServiceB”类型中不存在类型名称“XYZ”;
我的'服务B'有'ServiceB.SVC'
我试图通过删除命名空间“ServiceB”来克服这个问题。来自Reference.cs文件及其内容。然后可以编译此代码。
现在我得到了例外
“来电者未经过服务验证。”
内部异常
无法满足安全令牌请求,因为身份验证失败。
在System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(消息消息,EndpointAddress目标) 在System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage,SspiNegotiationTokenProviderState sspiState)
=>
((System.ServiceModel.FaultException)(ex.InnerException))。消息 无法满足安全令牌请求,因为身份验证失败。
ServiceB上的 Web.Config 文件如下:
<wsHttpBinding>
<binding name="WSHttpBinding_IABCService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://aaaaa/ ServiceA.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IABCService"
contract="XYZ.IABCService" name="WSHttpBinding_IABCService">
<identity>
<servicePrincipalName value="host/[hostname]" />
</identity>
</endpoint>
</client>
==
我让自己相信可能是WCF访问WCF的问题。我创建了一个Web服务(.asmx)并添加了对ServiceA的引用。当我通过调用方法调试时,我从ServiceA获得结果。希望这是一个我可以使用的解决方案,直到我弄清楚WCF和WCF问题之间,我添加了对我的WCF服务(ServiceB)的asmx服务的引用。 当我通过运行ServiceB调试 - &gt; asmx - &gt;服务A,我再次因用户错误而失败!
我认为这与身份冒充有关......
我读到ServiceB的web.config优先于asmx web.config,但我无法找到解决方案。
我无法关闭“安全模式=无”,因为服务A通过说没有通过令牌来回应。
任何帮助将不胜感激: 请记住,我可以使用WebApp和asmx中的WC Service A,但不能直接或间接使用其他WCF。
谢谢
月
答案 0 :(得分:2)
这与WCF调用WCF没有任何关系。试着想象WCF调用WCF会导致编译错误 - 而且自2006年以来你就是世界上第一个发现这个错误的人!
尝试完全限定“XYZ”类型,拼写出完整的命名空间。如果这不起作用,则右键单击每个服务引用,然后选择“在对象浏览器中查看”。看看这些类型的全名是什么。
如果这些都没有帮助您,请发布完整的错误消息和/或例外。
而且,请不要曾编辑Reference.cs。下次执行“更新服务参考”时,您的任何编辑都将被销毁。因此,您认为要对Reference.cs做出的任何更改都可以以更好的方式完成,而无需更改它,否则您确实不想要完全改变(例如你改变了。)
答案 1 :(得分:0)
在我看来,你需要有一个代表团而不是模仿。要将当前用户令牌转换为另一个令牌,您可以使用DuplicateToken
DuplicateTokenEx
(最后一个可以生成TokenPrimary
)SecurityDelegation
SecurityImpersonation
(SECURITY_IMPERSONATION_LEVEL
)然后WindowsIdentity(IntPtr)
构造函数。请参阅LogonUser and delegation作为示例。
另一种方式是协议转换:S4U,S4U2Self(见http://msdn.microsoft.com/en-us/magazine/cc163500.aspx,http://msdn.microsoft.com/en-us/library/ff650469.aspx,http://msdn.microsoft.com/en-us/library/ms998355.aspx)。您可以使用类似new WindowsIdentity(clientUPN).Impersonate()
的内容。
答案 2 :(得分:0)
如果您必须进行委托(即充当原始呼叫者),则会在this MSDN Forum thread上详细说明流程。不要使用完全信任委托 - 它需要AD的管理员权限,从安全角度来看这不是一件好事。如果您知道在SETSPN命令中使用哪些名称,则可以轻松正确设置约束委派。还要确保使用域用户帐户运行服务B(委派者),网络服务/本地服务等机器帐户或本地用户帐户将无法工作,因为您将无法为这些帐户创建SPN。