Spring MVC Spring WS在SOAP请求头中添加ValueType属性

goucqfw6  于 2023-05-07  发布在  Spring
关注(0)|答案(1)|浏览(159)

我正在使用Spring Web的SOAP客户端应用程序中工作,我需要调用一个需要使用Binary Security Token进行身份验证的外部服务。我有一个来自服务提供商团队的工作示例,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <wsse:BinarySecurityToken xmlns:wsst="http://www.ibm.com/websphere/appserver/tokentype/5.0.2" ValueType="wsst:LTPA">generated_token</wsse:BinarySecurityToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      ...
   </soapenv:Body>
</soapenv:Envelope>

this post为指导,我写了这个回调函数:

@Component
public class CrmBinarySecurityTokenHeaderCallback implements WebServiceMessageCallback {

    @Autowired
    private TokenGenerator tokenGenerator;

    @Override
    public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
        String securityToken = tokenGenerator.getToken();

        try {
            SaajSoapMessage saajSoapMessage = (SaajSoapMessage) webServiceMessage;
            SOAPMessage soapMessage = saajSoapMessage.getSaajMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
            SOAPHeader soapHeader = soapEnvelope.getHeader();

            Name headerElementName = soapEnvelope.createName("Security", "wsse",
                    "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            SOAPHeaderElement soapHeaderElement = soapHeader.addHeaderElement(headerElementName);
            SOAPElement securityTokenSoapElement = soapHeaderElement.addChildElement("BinarySecurityToken", "wsse");
            securityTokenSoapElement.addNamespaceDeclaration("wsst", "http://www.ibm.com/websphere/appserver/tokentype/5.0.2");

            QName valueType = securityTokenSoapElement.createQName("ValueType", "wsst");
            securityTokenSoapElement.addAttribute(valueType, "LTPA");

            securityTokenSoapElement.addTextNode(securityToken);

            soapMessage.saveChanges();
        } catch (SOAPException e) {
            throw new RuntimeException(e);
        }

    }
}

我得到的结果是这个XML:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <wsse:BinarySecurityToken xmlns:wsst="http://www.ibm.com/websphere/appserver/tokentype/5.0.2">
             generated_token
         </wsse:BinarySecurityToken>
      </wsse:Security>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      ...
</SOAP-ENV:Envelope>

你可以看到除了<wsse:BinarySecurityToken>元素中的ValueType="wsst:LTPA"之外,几乎是一样的。我一直在尝试使用SOAPElement API中的一些方法,如#addAttribute(),但无法添加此ValueType属性。
任何帮助和/或如何实现这一点的线索,是高度赞赏。提前感谢您的回答/评论。

sg3maiej

sg3maiej1#

最后,在检查了javax.xml.bind文档之后,我找到了解决方案。您可以使用SOAPEnvelope对象创建一个Name并将其添加为属性,如下所示:

@Override
    public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
        String securityToken = tokenGenerator.getToken();

        try {
            SaajSoapMessage saajSoapMessage = (SaajSoapMessage) webServiceMessage;
            SOAPMessage soapMessage = saajSoapMessage.getSaajMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
            SOAPHeader soapHeader = soapEnvelope.getHeader();

            Name headerElementName = soapEnvelope.createName("Security", "wsse",
                    "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            SOAPHeaderElement soapHeaderElement = soapHeader.addHeaderElement(headerElementName);
            SOAPElement securityTokenSoapElement = soapHeaderElement.addChildElement("BinarySecurityToken", "wsse");
            securityTokenSoapElement.addNamespaceDeclaration("wsst", "http://www.ibm.com/websphere/appserver/tokentype/5.0.2");

            // Create ValueType name...
            Name valueTypeName = soapEnvelope.createName("ValueType");
            // ... and add it as attribute
            securityTokenSoapElement.addAttribute(valueTypeName, "wsst:LTPA");

            securityTokenSoapElement.addTextNode(securityToken);

            soapMessage.saveChanges();
        } catch (SOAPException e) {
            throw new RuntimeException(e);
        }

    }

仅供参考,我检查的文档是:

希望这能帮助到别人。最好的问候

相关问题