JAX-WS добавить токен имени пользователя в заголовок SOAP

#java #xml #soap #jax-ws

#java #xml #soap #jax-ws

Вопрос:

У меня есть клиент JAX-WS, созданный из файлов WSDL. Настройка заголовков до сих пор работала со следующим кодом:

     WSBindingProvider bp = (WSBindingProvider) port;
    bp.setOutboundHeaders(
            Headers.create(new QName("http://schemas.xmlsoap.org/ws/2005/08/addressing", "To", "wsa"), "--To--"),
            Headers.create(new QName("http://schemas.xmlsoap.org/ws/2005/08/addressing", "Action", "wsa"), "--Action--"),
            Headers.create(new QName("http://schemas.xmlsoap.org/ws/2005/08/addressing", "MessageID", "wsa"), UUID.randomUUID().toString())
    );
  

Который выдает (по желанию) следующий фрагмент XML:

     <S:Header>
        <To
            xmlns="http://schemas.xmlsoap.org/ws/2005/08/addressing">--to--
        </To>
        <Action
            xmlns="http://schemas.xmlsoap.org/ws/2005/08/addressing">--action--
        </Action>
        <MessageID
            xmlns="http://schemas.xmlsoap.org/ws/2005/08/addressing">fe1b400a-e724-4486-8618-b1d36a0acbbb
        </MessageID>
    </S:Header>
  

Но мне нужны следующие связанные теги, которые я не смог получить с помощью Headers.create (…):

 <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken wsu:Id="PartnerId" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>--username--</wsse:Username>
    </wsse:UsernameToken>
</wsse:Security>
  

Есть идеи, как я могу добавить это в заголовок?

Ответ №1:

Следующий код работает для меня:

         private static final String SCHEMA = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
        private static final String SCHEMA_PREFIX = "wsse";
        private static final String USERNAME = "username";
        private static final String PASSWORD = "password";

        // Create a SOAP header
        try {
            SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope soapEnvelope = soapPart.getEnvelope();

            SOAPHeader header = soapEnvelope.getHeader();
            // Add the security SOAP header element
              SOAPHeaderElement security = header.addHeaderElement(new QName(SCHEMA, "Security", SCHEMA_PREFIX));
              SOAPElement usernameToken = security.addChildElement("UsernameToken", SCHEMA_PREFIX);
              SOAPElement usernameElement = usernameToken.addChildElement("Username", SCHEMA_PREFIX);
              SOAPElement passwordElement = usernameToken.addChildElement("Password", SCHEMA_PREFIX);
              Name typeName = soapEnvelope.createName("type");
              passwordElement.addAttribute(typeName, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
    
              usernameElement.setTextContent(USERNAME);
              passwordElement.setTextContent(PASSWORD);
    
              ((WSBindingProvider) webServicePort).setOutboundHeaders(Headers.create(security));
        } catch (SOAPException e) {
            logger.severe("Error setting SOAP header");
            e.printStackTrace();
        }
  

XML выглядит следующим образом:

 <?xml version="1.0" encoding="utf-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <env:Header>
        <wsse:Security env:mustUnderstand="1">
            <wsse:UsernameToken>
                <wsse:Username>username</wsse:Username>
                <wsse:Password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </env:Header>
    <env:Body>
    ...