在SOAP消息中使用wsse安全头(Visual Studio 2015,.Net Framework 4.5)

7
我想使用DHL提供的Soap服务。您可以在此处找到wsdl: https://wsbexpress.dhl.com/sndpt/expressRateBook?WSDL 因此,我在Visual Studio 2015中创建了一个新的ClassLibrary,以.NET Framework 4.5为目标。
然后,我通过提供wsdl地址向创建的项目添加了Web引用。我生成了一个包含所有类型和端口的代理文件,但我的第一个问题是:生成的服务扩展自System.Web.Services.Protocols.SoapHttpClientProtocol。根据最近的帖子,似乎无法将wsse头添加到该代理中。一些帖子建议添加wse,但似乎较新的Visual Studio版本不支持wse。
我尝试使用svcutil生成我的代理。之后,我将生成的.cs文件添加到项目中,并将生成的配置文件内容复制到app.config中。(当然,我删除了Web引用)现在,Service类扩展自System.ServiceModel.ClientBase。(我认为VS中的生成器内部使用svctool。如果微软希望人们使用wcf,为什么生成器会生成非wcf代理文件呢?)
我还创建了一个nunit测试项目,应该测试我的服务,但如果我使用由svcutil生成的版本,就会出现错误。我试图将其翻译成英语,因为错误是以德语显示的:
找不到指向服务合同的默认端点元素。据我了解,这是因为代理位于其自己的类库中,因此实际上没有app.config。但我的测试项目也是一个类库。
现在,如何消费需要ws安全性用户名/密码验证的Web服务?
2个回答

7
你可以在兼容模式下添加Web引用(我猜测你正在这样做)。如果你没有在兼容模式下添加引用,请按照以下步骤操作:
右键单击引用,选择添加服务引用 -> 高级 -> 添加Web引用(在兼容性部分下方),输入WS的URL并添加引用。
WSE2.0扩展可作为Nuget包使用:

https://www.nuget.org/packages/Microsoft.Web.Services2/

在包管理器控制台上运行以下NuGet命令安装NuGet包: Install-Package Microsoft.Web.Services2

安装NuGet包后,您需要确保项目引用了以下DLL:

  1. System.Web
  2. System.Web.Services
  3. Microsoft.Web.Services2(安装NuGet包后会自动添加)

为了使用WSE2.0扩展,您需要修改代理类以继承自“Microsoft.Web.Services2.WebServicesClientProtocol”,而不是“System.Web.Services.Protocols.SoapHttpClientProtocol”,该代理类是在添加Web引用时创建的。请注意,如果更新Web引用,则代理类将再次继承SoapHttpClientProtocol。

将以下using语句添加到使用代理类的代码中:

using Microsoft.Web.Services2;
using Microsoft.Web.Services2.Security;
using Microsoft.Web.Services2.Security.Tokens;

在您进行这些更改之后,您的代码应该看起来像这样:

var token = new UsernameToken("theUser", "thePassword", PasswordOption.SendHashed);

var serviceProxy = new ExpressRateBook.gblExpressRateBook();
SoapContext requestContext = serviceProxy.RequestSoapContext;
requestContext.Security.Timestamp.TtlInSeconds = 60;
requestContext.Security.Tokens.Add(token);
//The rest of the logic goes here...

我在下面附上了截图供您参考:

enter image description here

注意:由于我不熟悉您需要使用的实际方法,因此无法测试代码。显示的代码只是代理类中看到的示例,请根据您的需求进行更新。如果按照前面描述的步骤进行操作,应该可以正常工作。请查看以下链接以获取更详细的说明:

https://msdn.microsoft.com/en-us/library/ms819938.aspx


你不知道你是多么棒的人,这个解决方案完美地运作了,谢谢! - Shailesh Rama

0

您可以按照AW Rowse在http://cxdeveloper.com/article/implementing-ws-security-digest-password-nonce-net-40-wcf中描述的方式配置您的服务引用以添加安全头:

 private void Configure()
    {
        System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };

        defaultBinding = new BasicHttpBinding
        {
            Security =
            {
                Mode = BasicHttpSecurityMode.Transport,
                Transport =
                {
                    ClientCredentialType = HttpClientCredentialType.Digest
                }
            }
        };

        defaultToken = new UsernameToken(UserName, Password, PasswordOption.SendHashed);

        defaultSecurityHeader = MessageHeader.CreateHeader(
          "Security",
          "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
          defaultToken.GetXml(new XmlDocument())
        );
    }

然后像这样创建你的客户端/代理:

public consulta_informacao_respttClient CriaConsultaClinicaClient()
    {
        var client = new consulta_informacao_respttClient(defaultBinding, new EndpointAddress("https://resqa.homologacao.unimed.coop.br/chs-integration-external-services-ptu-clinical/proxy-services/execute-query/execute-query-proxy-service"));
        client.ClientCredentials.UserName.UserName = UserName;
        client.ClientCredentials.UserName.Password = Password;

        var scope = new OperationContextScope(client.InnerChannel);

        OperationContext.Current.OutgoingMessageHeaders.Add(defaultSecurityHeader);
        return client;
    }

创建类时需要定义的属性有:
private BasicHttpBinding defaultBinding;
private UsernameToken defaultToken;
private MessageHeader defaultSecurityHeader;

您不需要在app/web.config中进行任何配置。


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