使用.NET 3.0中的自定义消息/格式器将安全标题放入WCF服务
我们继承了具有自定义MessageFormatter的WCF Web服务,该自定义MessageFormatter在SerializeReply方法中构造了自定义Message子类。
class OurMessageFormatter : MessageFormatter { public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { OurResponse ourResponse = (OurResponse) result; // some validation here... OurMessage reply = new OurMessage(ourResponse, MessageVersion.Soap11); return reply; } }
我们面临的问题是自定义Message子类不会填充任何标头。我们试图看看WCF是否可以立即使用通用的填充(MessageID,ResponseTo,Action等),但是没有运气。然后我们意识到自定义Message子类已经实现了Headers属性,如下所示:
class OurMessage : Message { public override MessageHeaders Headers { get { return new MessageHeaders(MessageVersion.Soap11WSAddressing10); } } }
...事实证明是洛塔的帮助!所以我们照原样重写了它...
class OurMessage : Message { MessageHeaders headers; public OurMessage() { // ... headers = new MessageHeaders(MessageVersion.Soap11WSAddressing10); } public override MessageHeaders Headers { get { return headers; } } }
...仍然没有运气。
因此,我们继续手工编码标题。首先在格式化程序中...
class OurMessageFormatter : MessageFormatter { public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { //... OurMessage reply = new OurMessage(ourResponse, MessageVersion.Soap11); ourMessage.MessageID = ...; ourMessage.ResponseTo = ...; ourMessage.Action = ...; // more headers set ... return reply; } }
...然后是消息本身...
class OurMessage : Message { public override MessageHeaders Headers { get { MessageHeaders headers = new MessageHeaders(MessageVersion.Soap11WSAddressing10); ourMessage.MessageID = ...; ourMessage.ResponseTo = ...; ourMessage.Action = ...; // more headers set ... return headers; } } }
我们尝试过的每种方法都设法将WS-Addressing头放入实际响应中,但始终无法获得WS-Security头(实际上,我们只是尝试使用TimestampID和Created / Expires元素放入安全头)。每次我们在Security标头中添加Security标头时,该服务在序列化过程中(在SerializeReply调用完成后)都意外断开了连接。
所以这是我的问题。有谁知道如何通过自定义格式化程序和自定义消息实现将WS-Security标头添加到WCF服务中?
更新[2008年11月26日]:为此,我们遇到了一个严重的MS事件,从他们那里得到的最新更新是WCF的当前MessageVersion似乎不支持这些标头,需要自定义绑定实现。调查仍在继续,以寻求更好的方法。
解决方案
我注意到MessageHeaders类具有一个构造函数,该构造函数将MessageHeaders的集合作为参数。也许我们可以传递标头的完整集合,以查看其是否有效。我之前没有使用过WS-Security标头,因此不确定它们是否可行。我知道它们将位于自己的命名空间(wsse:http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd)中为消息头定义的。
我发现这篇文章很好地概述了邮件基础知识。它有一个创建标头的示例。