【发布时间】:2014-07-31 10:20:16
【问题描述】:
我正在尝试为 CRM 处于声明模式的 Microsoft Dynamics CRM 2011 ("xRM") Web 服务(我理解为基于 WCF 4)创建一个 Apache CXF (2.7.5) 客户端,所以该 Web 服务的 WSDL 指向一个 STS(在我的例子中是 AD FS 2.0)。
我的主要问题:是否有任何教程、建议、博客文章可以帮助我(描述如何发送声明,或者如何避免它们而使用 Windows 身份验证)?
下面是我到目前为止所做的描述。
我已经为同一个 Web 服务提供了工作代码,当 CRM 处于 Windows 身份验证模式时该服务工作。该代码基于"CXF and MS CRM 2011" on Groovy Tom's Blog。
为了支持声明模式,我还需要包含org.apache.cxf:cxf-rt-ws-mex,以便CXF 可以解析xRM WSDL。然后我需要让 CXF 内置的 STS 客户端使用 SOAP 1.2:
client.getRequestContext().put("ws-security.sts.client-soap12-binding", "true");
避免来自 AD FS 2.0 的错误 500。 (显然 AD FS 2.0 期望使用 SOAP 1.2 调用 /adfs/services/trust/mex 端点,而 CXF 默认为 SOAP 1.1。我必须从 AD FS's WCF trace 中找到这个,它报告了
System.ServiceModel.ProtocolException:内容类型文本/xml; charset=UTF-8 被发送到期望应用程序/soap+xml 的服务;字符集=utf-8。客户端和服务绑定可能不匹配。
当 Apache CXF 使用 SOAP 1.1 时。)
然后还有另一个问题:AD FS 的 /adfs/services/trust/mex 端点返回的 WSDL 似乎不完整,因为它包含
<wsdl:types>
<xsd:schema
targetNamespace="http://schemas.microsoft.com/ws/2008/06/identity/securitytokenservice/Imports">
<xsd:import namespace="http://schemas.microsoft.com/Message" />
<xsd:import namespace="http://schemas.xmlsoap.org/ws/2005/02/trust" />
<xsd:import namespace="http://docs.oasis-open.org/ws-sx/ws-trust/200512" />
</xsd:schema>
</wsdl:types>
所以imports 没有一个schemaLocation。这让CXF抱怨
org.apache.cxf.wsdl11.WSDLRuntimeException:部件请求定义为元素 {http://docs.oasis-open.org/ws-sx/ws-trust/200512}RequestSecurityToken 不在架构中。
我发现了造成这种情况的原因:包含 RequestSecurityToken 等的模式 在 mex SOAP 调用结果中,但在单独的 <wsx:MetadataSection Dialect="http://www.w3.org/2001/XMLSchema"> 部分中,AbstractSTSClient 中的代码完全忽略了这些部分.
所以我安装了我自己的 WSDLFactory+WSDLReader(使用属性 {{javax.wsdl.factory.WSDLFactory}}),它只是将三个命名空间的模式插入到它读取的任何 WSDL 中。
现在我在下一点被阻止:xRM WSDL(格式化后)包含http://www.w3.org/2005/08/addressing/anonymous 的Address(见下文),这会导致 CXF 在 AD FS 的元数据中查找该端点。但是,这样的端点当然不存在:它包含例如https://...:.../adfs/services/trust/2005/usernamemixed。
<wsdl:definitions
targetNamespace="http://schemas.microsoft.com/xrm/2011/Contracts/Services"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
snipped="other xmlns attributes">
<wsp:Policy wsu:Id="CustomBinding_IOrganizationService_policy">
<wsp:ExactlyOne>
<wsp:All>
<!-- snip -->
<sp:EndorsingSupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:IssuedToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<Issuer
xmlns="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<Address xmlns="http://www.w3.org/2005/08/addressing">
http://www.w3.org/2005/08/addressing/anonymous
</Address>
那我现在能做什么?
更一般地说,我现在的问题是:我是否走在为 xRM-in-claims-mode 构建 Java 客户端的正确道路上?其他人是如何让它工作的?或者有没有办法避免使用声明,而是使用带有 xRM-in-claims-mode 的 Windows 身份验证?
【问题讨论】:
标签: wcf dynamics-crm-2011 cxf claims-based-identity adfs