如何将WSSE安全头添加到大型多部分SOAP消息中?

时间:2016-12-08 21:15:11

标签: java web-services soap

我们有一个我们正在增强的Java Web服务,因此客户端可以向服务器发送一些非常大的消息。为了支持这些大型附件,我们正在使用MTOM。

不幸的是,我们还将WSSE安全信息添加到SOAP标头中,这导致了与超大SOAP消息结合的问题。

我们附加WSSE安全信息的代码在SOAPHandler中,如下所示:

public void addSecurity(String username, String password, SOAPMessageContext context) throws SOAPException {
    SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
    SOAPHeader header = envelope.getHeader();

    SOAPElement security = null;
    if (header == null) {
        header = envelope.addHeader();
    }
    security = header.addChildElement("Security", "wsse", WSSE_NS_URI);
    context.getMessage().saveChanges();

    SOAPElement usernameToken
            = security.addChildElement("UsernameToken", "wsse");
    usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
    SOAPElement usernameElement
            = usernameToken.addChildElement("Username", "wsse");
    usernameElement.addTextNode(username);

    SOAPElement passwordElement
            = usernameToken.addChildElement("Password", "wsse");
    passwordElement.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
    passwordElement.addTextNode(password);
}

失败发生在context.getMessage().getSOAPPart().getEnvelope()语句中。 context.getMessage()调用似乎试图获取整个消息,并且由于消息很大,我们得到堆空间错误:

Caused by: java.lang.OutOfMemoryError: Java heap space
    at com.sun.xml.internal.messaging.saaj.util.ByteOutputStream.ensureCapacity(ByteOutputStream.java:99)
    at com.sun.xml.internal.messaging.saaj.util.ByteOutputStream.write(ByteOutputStream.java:106)
    at org.apache.xml.serializer.WriterToUTF8Buffered.flushBuffer(WriterToUTF8Buffered.java:447)
    at org.apache.xml.serializer.WriterToUTF8Buffered.write(WriterToUTF8Buffered.java:191)
    at org.apache.xml.serializer.WriterToUTF8Buffered.write(WriterToUTF8Buffered.java:244)
    at org.apache.xml.serializer.ToStream.characters(ToStream.java:1623)
    at org.apache.xalan.transformer.TransformerIdentityImpl.characters(TransformerIdentityImpl.java:1126)
    at org.apache.xml.serializer.TreeWalker.dispatachChars(TreeWalker.java:246)
    at org.apache.xml.serializer.TreeWalker.startNode(TreeWalker.java:416)
    at org.apache.xml.serializer.TreeWalker.traverse(TreeWalker.java:145)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:390)
    at com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:399)
    at com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl.output(EnvelopeImpl.java:289)
    at com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl.output(EnvelopeImpl.java:302)
    at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getContentAsStream(SOAPPartImpl.java:311)
    at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.getHeaderBytes(MessageImpl.java:1015)
    at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.saveChanges(MessageImpl.java:1166)
    at com.sun.xml.internal.ws.api.message.saaj.SAAJFactory.readAsSOAPMessage(SAAJFactory.java:277)
    at com.sun.xml.internal.ws.api.message.saaj.SAAJFactory.readAsSAAJ(SAAJFactory.java:197)
    at com.sun.xml.internal.ws.api.message.saaj.SAAJFactory.read(SAAJFactory.java:186)
    at com.sun.xml.internal.ws.message.AbstractMessageImpl.toSAAJ(AbstractMessageImpl.java:217)
    at com.sun.xml.internal.ws.api.message.MessageWrapper.readAsSOAPMessage(MessageWrapper.java:156)
    at com.sun.xml.internal.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:70)
    at com.ciminc.compass.singleSignOn.basic.SsoCookieRequestAppender.addSecurity(SsoCookieRequestAppender.java:147)

理想情况下,我想将我的WSSE信息添加到SOAP标头中,而不需要引入整个多兆字节的SOAP消息。这可能吗?

如果我能提供任何其他信息以澄清,请告诉我。

0 个答案:

没有答案