我对SOAP的了解很少,所以请原谅我的无知。我正在尝试调用要求令牌包含在请求标头中的服务。
该服务的WSDL文件包含以下内容:
</wsdl:service>
<wsp:Policy wsu:Id="SecurityPolicy">
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:HashPassword/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
在服务的某些文档中,我发现标题应该类似于以下内容:
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-14" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>CycwgQOZ1CTy5Zv59…</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">kkn3cjhx4gvIhULfap6MLYDc8qc=
</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">EeDyyCxk4x97BNh0cUjaIA==
</wsse:Nonce>
<wsu:Created>2015-01-22T11:58:10.591Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
但是,我认为随机数不是严格必需的,因为我可以在不指定随机数的情况下调用此服务(使用SOAP UI),并且它对我有用。我只指定以下内容:
如以下屏幕截图所示:
我的主要问题是如何以编程方式构造相同的请求。我发现不同的人提出了几种不同的方法。有些涉及使用拦截器,有些似乎涉及使用依赖项特定的类来构造标头。令人沮丧的是,我看到的所有示例似乎彼此都有些不同!
我目前正在尝试底部显示的方法,但出现异常:
org.apache.cxf.ws.policy.PolicyException: None of the policy alternatives can be satisfied.
以下是控制台中写的最后两行:
12:04:14.630 [main] DEBUG o.a.cxf.ws.policy.PolicyEngineImpl - Alternative {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}UsernameToken is not supported
12:10:52.378 [main] DEBUG o.a.cxf.ws.policy.PolicyEngineImpl - Alternative {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}UsernameToken is not supported
我已经调试了它,我认为以下内容可能对该问题有所帮助(我希望这不是一个红鲱鱼)。我看到它进入类org.apache.cxf.ws.policy.PolicyEngineImpl,并在方法“ supportsAlternative”中检查该策略是否存在于变量pipr中,该变量在行中声明:
PolicyInterceptorProviderRegistry pipr =
bus.getExtension(PolicyInterceptorProviderRegistry.class);
在我的测试中,此pipr包含78个不同的元素,例如:
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}ProtectTokens=[{}, {}]
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SignedEncryptedSupportingTokens=[{}, {}]
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}ContentEncryptedElements=[{}, {}]
...
但是它似乎不包含“ UsernameToken”,这似乎是导致我当前异常的原因。如以下屏幕截图所示。
我当前的代码如下:
MyServiceClass service = new MyServiceClass();
serviceName = service.getServiceName().toString();
logger.info("serviceName: " + serviceName);
port = service.getMyPort();
// not sure if this is needed. The endpoint URL is also set within the service
BindingProvider provider = (BindingProvider) port;
String fullUrl = THE_FULL_URL_INCLUDING_HTTP;
provider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, fullUrl);
Map<String, Object> props = new HashMap<>();
props.put("action", "UsernameToken");
props.put("user", token);
props.put("passwordType", "PasswordText");
WSS4JOutInterceptor wss4jOut = new WSS4JOutInterceptor(props);
client.getOutInterceptors().add(wss4jOut);
((BindingProvider) port).getRequestContext().put("password", THE_PASSWORD);
HTTPConduit httpConduit = (HTTPConduit) ClientProxy.getClient(securityServiceClient).getConduit();
TLSClientParameters tlsParams = new TLSClientParameters();
setupHttpPolicy(httpConduit);
setupSsl(tlsParams);
setupCertNameCheck(tlsParams);
httpConduit.setTlsClientParameters(tlsParams);
port.doCall();
为什么我会收到例外?我需要怎么做才能使其正常工作?