Как использовать политику «UsernameToken» для включения токена в заголовок запроса на мыло - PullRequest
0 голосов
/ 29 марта 2019

У меня очень мало опыта работы с 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

Мой главный вопрос - как построить тот же запрос программно.Я нашел несколько разных подходов, предложенных разными людьми.Некоторые включают использование Interceptor, другие, кажется, включают использование определенных классов зависимости для создания заголовка.Немного расстраивает то, что все примеры, которые я вижу, немного отличаются друг от друга!

В настоящее время я пробую подход, показанный внизу, но получаю исключение:

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, а в методе "SupportAlternative" он проверяет, существует ли политика в переменной 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();

Почему я получаю исключение?что мне нужно сделать, чтобы заставить его работать?

...