如何使用策略“ UsernameToken”在肥皂请求的标头中包含令牌

时间:2019-03-29 12:58:40

标签: java web-services authentication soap cxf-codegen-plugin

我对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),并且它对我有用。我只指定以下内容:

  • 用户名
  • 密码
  • 将密码类型设置为“密码摘要”

如以下屏幕截图所示:

enter image description here

我的主要问题是如何以编程方式构造相同的请求。我发现不同的人提出了几种不同的方法。有些涉及使用拦截器,有些似乎涉及使用依赖项特定的类来构造标头。令人沮丧的是,我看到的所有示例似乎彼此都有些不同!

我目前正在尝试底部显示的方法,但出现异常:

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”,这似乎是导致我当前异常的原因。如以下屏幕截图所示。

enter image description here

我当前的代码如下:

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();

为什么我会收到例外?我需要怎么做才能使其正常工作?

0 个答案:

没有答案