如何向SOAP消息添加安全头?

8
我正在尝试从我们的C#应用程序调用供应商编写的Java WebService。当通信时,我收到以下消息: WSDoAllReceiver:传入消息不包含所需的安全标头。 自昨天以来,我一直在尝试找出如何向SOAP消息添加安全标头。 是的,我看过了这个(Clueless about how to create SOAP <wsse:Security> header),但没有起作用。 我四处查找,这似乎是一个相当常见的问题。我想知道是否可以在这里获得一些帮助,一些指针,一些代码,让我开始。
2个回答

15
我实际上通过使用WSE来实现这一点。有趣的是,该提供商的Web服务无法与WSE 3.0配合使用,但它们可以与WSE 2.0配合使用。以下是步骤:
  • 获取WSE 2.0
  • 将Web引用添加到项目中
  • 在Web引用代理实现中:

替换

public partial class UserWS : System.Web.Services.Protocols.SoapHttpClientProtocol

public partial class UserWS : Microsoft.Web.Services2.WebServicesClientProtocol
  • 调用Web服务之前:

设置身份验证信息

UsernameToken token = new UsernameToken("user", "pwd", PasswordOption.SendPlainText);
yourProxy.RequestSoapContext.Security.Tokens.Add(token);

就是这样!顺便提一下,供应商是Blackboard实例。


那么使用WCF消费Blackboard Web服务不可能吗? - Anthony Serdyukov
@AdrianCarneiro - 超级棒! - Gurucharan Balakuntla Maheshku
1
每次有人更新网络引用时,引用都会被清除(我需要再次将其设置为microsoft.web.services2)。有没有办法阻止这种情况发生或者说无法阻止? - n00b
@AdrianCarneiro哪个类是Web服务代理实现?我没有任何继承自SoapHttpClientProtocol的类。 - Laggel
2
WSE 2.0可以通过Nuget添加到您的项目中。https://www.nuget.org/packages/Microsoft.Web.Services2/ - Mark Dornian
@Laggel 你确定你使用了WSE来生成你的代码吗?如果你使用了WCF,那么客户端的签名将会有所不同,并且会包括绑定作为一个参数,可以像https://dev59.com/Deo6XIcBkEYKwwoYTSsu中描述的那样使用。在VS2020中,我并没有立刻发现如何使用WSE或WCF来生成代码,但这两种方法仍然是可行的。 - B5A7

4

试试这个方法。无需网络引用和Web.Services2实现。

var client = "Your Service Client"; 
using (var scope = new OperationContextScope(client.InnerChannel))
{
    System.Xml.XmlDocument document = new XmlDocument();
    XmlElement element = document.CreateElement("wsse", "UsernameToken", 
       "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

    XmlElement newChild = null;
    newChild = document.CreateElement("wsse", "Username", 
       "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    newChild.InnerText = "finance";
    element.AppendChild(newChild);

    newChild = document.CreateElement("wsse", "CorporationCode", 
       "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    newChild.InnerText = "387";
    element.AppendChild(newChild);

    MessageHeader messageHeader = MessageHeader.CreateHeader("UsernameToken", 
       "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", 
        element, false);

// shouldn't MessageHeader be Security?
//  MessageHeader messageHeader = MessageHeader.CreateHeader("Security", ...

    OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);

    var result = client.GetCorporations(new CorporationType { pageNo = 1 });
}

1
认为在wsse部分缺少顶级安全性。 - SteveC
我使用了这里提到的解决方案,基本上做的是同样的事情,但可能更容易理解。https://dev59.com/K3RB5IYBdhLWcg3wEDul#8747583 - Plater

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接