首页 > 解决方案 > JAX-WS 将 Username-Token 添加到 SOAP-Header

问题描述

我有一个从 WSDL 文件生成的 JAX-WS 客户端。到目前为止,设置标题使用以下代码:

    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>

有什么想法可以将其添加到标题中吗?

标签: javaxmlsoapjax-ws

解决方案


以下代码适用于我:

        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>
    ...


推荐阅读