[英]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
提出了一個適用於我的目的的替代解決方案。
AttachmentPart
並將步驟2中的內容注入其中。 它也需要Base64編碼的文本,這很方便。 然后, AttachmentPart
為Content-Id
分配了一個引用UUID。 然后,我創建一個新元素來代替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.