簡體   English   中英

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

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

目前,我有兩個處理程序,一個用於日志記錄,另一個用於簽名SOAP消息(它本身就是篡改SOAP消息)。 如果沒有處理程序鏈,MTOM將按預期工作,插入對二進制內容的引用,而不是內聯base64二進制內容。

一旦我引入了處理程序,MTOM內容現在就包含在內聯中。

是否可以使用處理程序來簽署SOAP消息,或者是否有更合適的方法來執行此操作?

更新1無法發布完整的源。 基本上,自定義SOAPHandler實現。 它在時間戳(在標頭中),自定義頭和SOAP主體上執行一些基本的XMLDsig類型操作。 然后將得到的摘要值注入標題中的簽名元素。

關於記錄器,它又是一個簡單的SOAPHandler。 如果它或它是唯一使用的簽名處理程序,結果是相同的,一個內聯字節內容的MTOM消息。 我做的唯一進步是使用MessageHandler進行日志記錄。 這允許我輸出SOAP信封(雖然內聯字節內容)並仍然保持MTOM分離。 所以不是真正的解決方案,而是指示SOAP消息的任何修改都需要在較低級別進行。 這引導我走下管道。

更新2

以下是MessageHandler方法的示例。 您可以看到原始HTTP轉儲將包含多部分消息,而實際輸出則內聯base64。 此實現與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;
}

我嘗試通過組合一個接受MTOM傳輸的圖像的簡單服務來復制您的問題。 我發現如果設置處理程序之前放入啟用MTOM的代碼,它會正確編碼消息。 如果我先設置處理程序,則不會。 這是我設置正常運行的客戶端代碼的地方:

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;
    }
});

其中RGBSOAPHandler只是我從另一個SO答案中獲取的一些示例代碼。

編輯:此外,如果我嘗試在綁定而不是服務上設置處理程序,那么我會遇到與您相同的問題。 所以,如果它看起來像這樣:

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);

然后我的文件在線編碼。 我不知道為什么會這樣,但我想答案是“不要那樣做”。 Service對象上設置處理程序。

看起來我受到框架和處理程序工作方式的限制。 我認為在現階段,我唯一的選擇就是降低水平。 我確實看過使用電子管但是同樣的行為表現出來,所以看起來任何嘗試使用XML的請求都失敗了。 因此,我將不得不暫時放棄處理程序,並在較低級別調查我是否可以使用編解碼器來完成我所追求的目標。 一個MTOM實現聽起來像它可能做我在字節級別后的事情:

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

我想,這樣做起來要復雜得多,但會隨着我在編解碼器方面的進展而更新。

@David:感謝您在處理程序方面的幫助,但看起來好像在該級別沒有解決方案。

更新1

提出了一個適用於我的目的的替代解決方案。

  1. 我使用SOAPHandler簽署SOAP消息的必要部分。
  2. 編寫了一個新的SOAPHandler,然后獲取結果消息並手動提取錯誤內聯的二進制內容。
  3. 然后我創建一個AttachmentPart並將步驟2中的內容注入其中。 它也需要Base64編碼的文本,這很方便。 然后, AttachmentPartContent-Id分配了一個引用UUID。
  4. 然后,我創建一個新元素來代替SOAP主體中引用UUID的Base64內容,沿着以下行:

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

可能會寫一篇關於此的博客文章,因為這是一個關於這一點的史詩般的旅程。 這不是最好的解決方案,但它肯定比管/編解碼器路徑更容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM