简体   繁体   English

如何使用SOAPHandlers签署MTOM SOAP消息?

[英]How do I sign an MTOM SOAP message using SOAPHandlers?

Currently, I have two handlers, one for logging and one for signing the SOAP message (which inherently tampers with the SOAP message). 目前,我有两个处理程序,一个用于日志记录,另一个用于签名SOAP消息(它本身就是篡改SOAP消息)。 Without the handler chain, MTOM works as expected, inserting a reference to the binary content, rather than inlining the base64 binary content. 如果没有处理程序链,MTOM将按预期工作,插入对二进制内容的引用,而不是内联base64二进制内容。

As soon as I introduce a handler, the MTOM content is now included inline. 一旦我引入了处理程序,MTOM内容现在就包含在内联中。

Is it possible to use handlers to sign a SOAP message or is there a more appropriate means of doing this? 是否可以使用处理程序来签署SOAP消息,或者是否有更合适的方法来执行此操作?

Update 1 Unable to post the full source. 更新1无法发布完整的源。 Essentially though, custom SOAPHandler implementation. 基本上,自定义SOAPHandler实现。 It performs some basic XMLDsig type operations on a timestamp (in header), custom header and SOAP body. 它在时间戳(在标头中),自定义头和SOAP主体上执行一些基本的XMLDsig类型操作。 The resultant digest values are then injected into a signature element in the header. 然后将得到的摘要值注入标题中的签名元素。

With respect to the logger, it is again a simple SOAPHandler. 关于记录器,它又是一个简单的SOAPHandler。 If either it or the signing handler are used exclusively, the result is the same, an MTOM message with the byte content inlined. 如果它或它是唯一使用的签名处理程序,结果是相同的,一个内联字节内容的MTOM消息。 The only progress I made was using a MessageHandler for logging. 我做的唯一进步是使用MessageHandler进行日志记录。 This allowed me to output the SOAP envelope (albeit with the byte content inlined) and still maintain the MTOM separation. 这允许我输出SOAP信封(虽然内联字节内容)并仍然保持MTOM分离。 So not really a solution but an indication that any modification of the SOAP message needs to occur at a lower level. 所以不是真正的解决方案,而是指示SOAP消息的任何修改都需要在较低级别进行。 This is leading me down the path of tubes. 这引导我走下管道。

Update 2 更新2

The following is an example of the MessageHandler approach. 以下是MessageHandler方法的示例。 You can see that the raw HTTP dump will contain the multiple part message whereas the actually output inlines the base64. 您可以看到原始HTTP转储将包含多部分消息,而实际输出则内联base64。 The only difference between this impementation and a SOAPHandler implementation is that the actual HTTP request changes to be a single part inlined MTOM message. 此实现与SOAPHandler实现之间的唯一区别是实际的HTTP请求更改为单个部分内联MTOM消息。

@Override
public boolean handleMessage(MessageHandlerContext context) {

  HttpTransportPipe.dump = true;

  Boolean isOutgoing = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

  if (isOutgoing) {
    System.out.println("\nOutbound message:");
    XMLStreamWriter writer = XMLStreamWriterFactory.create(System.out);
    try {
      context.getMessage().writeTo(writer);
    } catch (XMLStreamException e) {
      throw new IllegalStateException("Unable to write");
    }
  } else {
    System.out.println("\nInbound message:");
  }
  return true;
}

I tried to replicate your problem by putting together a simple service that accepts an image transferred by MTOM. 我尝试通过组合一个接受MTOM传输的图像的简单服务来复制您的问题。 I found that if I put the MTOM-enabling code before setting the handler, it encodes the message properly. 我发现如果设置处理程序之前放入启用MTOM的代码,它会正确编码消息。 If I set the handler first, it does not. 如果我先设置处理程序,则不会。 Here is where I set up the properly functioning client code: 这是我设置正常运行的客户端代码的地方:

Service service = Service.create(url, qname);

Greeting greeting = service.getPort(Greeting.class);

BindingProvider bp = (BindingProvider) greeting;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);

service.setHandlerResolver(new HandlerResolver() {
    @SuppressWarnings("rawtypes")
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerList = new ArrayList<Handler>();
        handlerList.add(new RGBSOAPHandler());
        return handlerList;
    }
});

Where RGBSOAPHandler is just some example code I took from another SO answer . 其中RGBSOAPHandler只是我从另一个SO答案中获取的一些示例代码。

EDIT: Also, if I try setting the handler on the binding and not the service then I get the same problem that you do. 编辑:此外,如果我尝试在绑定而不是服务上设置处理程序,那么我会遇到与您相同的问题。 So if it looks like this: 所以,如果它看起来像这样:

Service service = Service.create(url, qname);

Greeting greeting = service.getPort(Greeting.class);

BindingProvider bp = (BindingProvider) greeting;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);

List<Handler> handlerList = new ArrayList<Handler>();
handlerList.add(new RGBSOAPHandler());
binding.setHandlerChain(handlerList);

Then my file is encoded in-line. 然后我的文件在线编码。 I don't know why this is, but I suppose the answer is "don't do that". 我不知道为什么会这样,但我想答案是“不要那样做”。 Set your handlers on the Service object. Service对象上设置处理程序。

Looks like I'm limited by the framework and the way in which the handlers work. 看起来我受到框架和处理程序工作方式的限制。 I think at this stage, my only option is to go to a lower level. 我认为在现阶段,我唯一的选择就是降低水平。 I did take a look at using tubes but the same behaviour exhibited itself so it looks as though any attempt to work with the XML of the request fails. 我确实看过使用电子管但是同样的行为表现出来,所以看起来任何尝试使用XML的请求都失败了。 As such, I'm going to have to abandon handlers for the time being and investigate at a lower level whether I can make use of codecs to do what I'm after. 因此,我将不得不暂时放弃处理程序,并在较低级别调查我是否可以使用编解码器来完成我所追求的目标。 An MTOM implementation sounds like it may do what I'm after at the byte level: 一个MTOM实现听起来像它可能做我在字节级别后的事情:

http://jax-ws.java.net/nonav/jax-ws-20-fcs/arch/com/sun/xml/ws/encoding/MtomCodec.html http://jax-ws.java.net/nonav/jax-ws-20-fcs/arch/com/sun/xml/ws/encoding/MtomCodec.html

I imagined this would be a lot less complex to get working but will update with my progress on the codec front. 我想,这样做起来要复杂得多,但会随着我在编解码器方面的进展而更新。

@David: Thanks for your help on the handler front but looks as though there is no solution at that level. @David:感谢您在处理程序方面的帮助,但看起来好像在该级别没有解决方案。

Update 1 更新1

Came up with an alternate solution that works for my purposes. 提出了一个适用于我的目的的替代解决方案。

  1. I sign the necessary parts of the SOAP message using my SOAPHandler. 我使用SOAPHandler签署SOAP消息的必要部分。
  2. Wrote a new SOAPHandler that then takes resultant message and manually extracts the incorrectly inlined binary content. 编写了一个新的SOAPHandler,然后获取结果消息并手动提取错误内联的二进制内容。
  3. I then create an AttachmentPart and inject the content from Step 2 into that. 然后我创建一个AttachmentPart并将步骤2中的内容注入其中。 It takes Base64 encoded text too which is handy. 它也需要Base64编码的文本,这很方便。 That AttachmentPart then has a reference UUID assigned to it for Content-Id . 然后, AttachmentPartContent-Id分配了一个引用UUID。
  4. I then create a new element in place of the Base64 content in the SOAP body that reference the UUID, along the lines of the following: 然后,我创建一个新元素来代替SOAP主体中引用UUID的Base64内容,沿着以下行:

     <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:UUID!!!"></xop:Include> 

Will probably write a blog post on this as it's been a bit of an epic journey to this point. 可能会写一篇关于此的博客文章,因为这是一个关于这一点的史诗般的旅程。 It was not the best solution but it was certainly easier than going down the tubes/codec path. 这不是最好的解决方案,但它肯定比管/编解码器路径更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM