我试图创建一个Apache CXF(2.7.5)客户端,用于Microsoft Dynamics CRM 2011(xRM)Web服务(我理解为基于WCF 4),其中CRM处于索赔模式,因此此Web服务的WSDL指向STS(在我的情况下AD FS 2.0)。
我的主要问题是:是否有任何教程、建议和博客帖子可以帮助我(或者描述如何发送声明,或者如何避免声明,而是使用Windows身份验证)?
下面是我到目前为止所做工作的描述。
我已经有了相同网络服务的工作代码,当客户关系管理处于视窗身份验证模式时,该服务可以工作。该代码基于Groovy Tom's Blog上的CXF and MS CRM 2011。
为了支持索赔模式,我还需要加入org。阿帕奇。cxf:cxf rt ws-mex,这样xRM WSDL就可以被cxf解析。然后我需要让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/mexendpoint,而CXF默认为SOAP 1.1。我必须从AD FS的WCF跟踪中找到这一点,该跟踪报告
系统服务模型。ProtocolException:内容类型text/xml;charset=UTF-8被发送到一个需要应用程序/soap xml的服务;字符集=utf-8。客户端和服务绑定可能不匹配。
当Apache CXF使用SOAP 1.1。(
然后还有另一个问题:AD FS /adfs/services/trust/mexendpoint返回的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>
因此,import
s中没有一个具有schemaLocation
。这让CXF抱怨
org.apache.cxf.wsdl11。WSDLRuntimeExcema:部分请求定义为元素{http://docs.oasis-open.org/ws-sx/ws-trust/200512}请求安全令牌,该元素不在模式中。
我发现了是什么导致了这种情况:包含的模式是在mex SOAP调用结果中,但在单独的
中。
因此,我放置了自己的WSDLFactory WSDLReader(使用属性{javax.wsdl.factory.WSDLFactory}),它只将三个名称空间的模式插入到它读取的任何wsdl中。
现在我在下一点被阻止了:xRM WSDL(格式化后)包含一个
地址
http://www.w3.org/2005/08/addressing/anonymous
(见下文),这会以某种方式导致CXF在AD FS的元数据中查找该endpoint。然而,这样的endpoint当然不存在:它包含,例如,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构建Java客户机的道路是否正确?其他人是怎么做到的?或者有没有办法避免使用声明,而是在声明模式下使用Windows身份验证和xRM?
我已经将“匿名”问题的修复程序合并到CXF:
https://issues.apache.org/jira/browse/CXF-5807
当颁发者地址为“匿名”时,您可以通过元数据指定所需的STSendpoint名称,否则它将退回到只选择接收到的WSDL中的第一个端口。
科尔姆。
我们最终实现了它,不仅使用了Groovy Tom的博客上的“CXF和MS CRM 2011”,我在这个问题中提到过,还使用了Jan Hendrik Kuperus在JH on Java博客(archive.org cached copy)上的“使用Apache CXF连接到Microsoft Dynamics”,此外还修改了(?)adfs2.0wsdl。
不幸的是,出于许可的原因,我不能直接发布任何代码,但下面是我们所做工作的概述。
Jan Hendrik Kuperus解决方案的关键部分是我们创建自己的STSClient,而不是让CXF创建一个。这解决了被忽略的
在该定制STS客户端中,我们指向特定的AD FSendpoint,确保使用SOAP 1.2(防止HTTP错误500,请参阅问题),并关闭“续订”:
STSClient stsClient = new STSClient(bus);
stsClient.setSoap12();
stsClient.setWsdlLocation(wsdlLocation.toExternalForm());
stsClient.setServiceQName(new QName("http://schemas.microsoft.com/ws/2008/06/identity/securitytokenservice", "SecurityTokenService"));
stsClient.setEndpointQName(new QName("http://schemas.microsoft.com/ws/2008/06/identity/securitytokenservice", "UserNameWSTrustBinding_IWSTrust13Async"));
stsClient.setSendRenewing(false);
(如果未关闭续订,则AD FS 2.0返回SOAP错误ID3035:请求无效或格式错误。AD FS跟踪表示"Microsoft.识别模型。SecurityTokenService.Invalid刚需异常:MSIS3137:刚需安全令牌元素包含一个不受支持的WS-Trust参数:'Renewing'。(
现在在请求上下文中的属性
Security常量下注册
(stsClient
。STS_CLIENT"ws-security.sts.client"
),设置请求上下文属性Security常量。USERNAME
,并且在属性Security常量中。CALLBACK_HANDLER
注册一个CallbackHandler
,它处理生成的WSPasswordCallback
并设置密码,您就可以开始工作了。除了。
除了在那一点上,我们发现CXF 2.7.5阻塞了AD FS的WSDL:
java.lang.IllegalArgumentExc0019: sp: KeyValueToken/wsp:策略必须在KeyValueTokenBuilder#build()中有一个值
。事实证明,WSDL包含许多具有属性wsp:可选="true"
的安全策略,对于这些策略中的每一个,CXF都期望嵌套
(我们不知道CXF 2.7.5在这里是否过于严格,或者AD FS 2.0的WSDL是否不符合标准。)
此外,通过查看
private static class XRMAuthSecurityModeInterceptor extends AbstractSoapInterceptor {
public XRMAuthSecurityModeInterceptor() {
super(Phase.PREPARE_SEND);
addBefore("IssuedTokenOutInterceptor");
}
public void handleMessage(SoapMessage message) throws Fault {
// if the custom assertion with security mode Federation is present, then create STSClient and...
message.setContextualProperty(SecurityConstants.STS_CLIENT, stsClient);
}
}
最后,由于我们不想使用AD FS的WSDL的下载版本,所以我们通过获取
SP12常量,在同一个'out拦截器'中对该WSDL进行了'修复'。ISSUED_TOKEN断言,获取它的
. getIssuerEpr(). getMetadata(). getany()
,并从中获得{http://www.w3.org/2005/08/addressing}地址
。结果类似http://example.com:12345/adfs/services/trust/mex.我们检索该URL,解析XML,添加
希望这能帮助其他人;如果你不能让它发挥作用,请随时提问。
问题内容: 到现在为止,我主要是利用,,用于构建Web应用程序技术堆栈。关键是,提到的堆栈使用服务器端模式。Web浏览器的主要作用仅限于请求/响应周期(+客户端验证)。数据检索,业务逻辑,接线和验证是服务器端的主要职责。 我对 AngularJS 框架有几个疑问,这些疑问是由我阅读过以下引号引起的: 从 AngularJS教程中 : 对于Angular应用,我们鼓励使用Model-View-Con
关于AngularJS框架,我有几个问题是从我读到的以下引用中得到启发的: 从AngularJS教程: 对于有角度的应用程序,我们鼓励使用Model-View-Controller(MVC)设计模式来解耦代码并分离关注点。 我知道我的问题有些奇怪,但我认为原因是,我对传统的服务器端MVC模式有些敏感。我确信有人已经做了同样的转变。
问题内容: 有了JSR 311及其实现,我们有了一个强大的标准,可以通过REST公开Java对象。但是,在客户端,似乎缺少与SOAP的Apache Axis类似的东西-隐藏了Web服务并将数据透明地封送回Java对象的东西。 您如何创建Java RESTful客户端?使用HTTPConnection和手动解析结果?还是专业客户(例如Jersey或Apache CXR)? 问题答案: 这是一个古老的
问题内容: 我正在开发一个项目,该项目需要解析一些受保护的网页中的数据。为了获得对这些页面的访问权限,我必须克服SAML身份验证形式(Shibboleth)。是否有人能够在Android(Java)中实现此标准?我已经读过这个线程:Android的SAML客户端实现? 但这并不能给我一个很好的解决方案。实际上,我需要 获取某些受保护网页的数据 以便对其进行解析,而不是让用户看到此类网页的内容。因此
问题内容: 有人知道iOS的Elasticsearch客户端库吗?如果它也是迅速写的,那将是一个好处。 elasticsearch的“客户端”部分显示了多个平台的多个库,但对于iOS没有任何显示,我觉得有人必须这样做吗? 干杯 问题答案: 我怀疑是否有人- 上次我检查时没有,并且有充分的理由。请记住,为了允许IOS客户端(或Android)使用客户端库连接到Elasticsearch,您必须打开集
问题内容: 我正在尝试从Java连接到ElasticSearch,但只能通过HTTP连接。我不能使用。ElasticSearch REST API周围是否有Java客户端包装?如果可以,该如何使用? 问题答案: 嗨,有一个全新的项目正好满足您的需求。基于Java的RestAPI for Elasticsearch 看看这个!它的名字是JEST