简体   繁体   English

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

[英]Use wsse security header in soap message (Visual Studio 2015, .Net Framework 4.5)

I would like to consume a Soap Service provided by DHL. 我想使用DHL提供的肥皂服务。 You can find the wsdl here: https://wsbexpress.dhl.com/sndpt/expressRateBook?WSDL 你可以在这里找到wsdl: https//wsbexpress.dhl.com/sndpt/expressRateBook?WSDL

Therefore I created a new ClassLibrary in Visual Studio 2015 targeting .net framework 4.5. 因此,我在Visual Studio 2015中创建了一个新的ClassLibrary,目标是.net framework 4.5。

Then I added a Web Reference to the created project by providing the wsdl address. 然后,我通过提供wsdl地址为创建的项目添加了Web引用。 I generated a proxy file with all types and ports in it but my first problem is, that the generated Service extends from System.Web.Services.Protocols.SoapHttpClientProtocol . 我生成了一个包含所有类型和端口的代理文件,但我的第一个问题是,生成的Service扩展自System.Web.Services.Protocols.SoapHttpClientProtocol As I read in recent posts it is not possible to get the wsse header to that proxy. 正如我在最近的帖子中读到的那样,不可能将wsse标头带到该代理。 Some posts advise to add wse but it seems wse is not supported by newer Visual Studio versions. 一些帖子建议添加wse但似乎wse不受新版Visual Studio版本的支持。

I tried to generate my proxy by svcutil. 我尝试通过svcutil生成我的代理。 After that I added the generated .cs file to the project and copied the content of the generated config file to app.config. 之后,我将生成的.cs文件添加到项目中,并将生成的配置文件的内容复制到app.config。 (of cause I removed the web reference) Now the Service class extends System.ServiceModel.ClientBase . (因为我删除了Web引用)现在Service类扩展了System.ServiceModel.ClientBase (I thought the generator in VS uses svctool internally. If microsoft want people to use wcf why does the generator generate non-wcf proxy files. (我认为VS中的生成器在内部使用svctool。如果microsoft希望人们使用wcf,为什么生成器会生成非wcf代理文件。

I also created a nunit testproject which should test my service, but If I use the version with the svcutil generated version I get an error. 我还创建了一个nunit testproject,它应该测试我的服务,但是如果我使用带有svcutil生成版本的版本,我会收到一个错误。 I try to translate it to english as the error is displayed in german: 因为错误以德语显示,我尝试将其翻译为英语:

Could not find a default endpoint element which points to the service contract. 找不到指向服务合同的默认端点元素。 As I figured out this is because the proxy is in its own class library and therefor doesn't really have an app.config. 我发现这是因为代理在它自己的类库中,因此没有真正的app.config。 But my test project is a class library too. 但我的测试项目也是一个类库。

What would be the actual way to consume a web service which needs ws security Username/Password auth these days? 这些天消费需要ws安全用户名/密码的Web服务的实际方法是什么?


You can add the Web Reference in compatibility mode (I am guessing you are doing so). 您可以在兼容模式下添加Web引用(我猜您正在这样做)。 If you are not adding the reference in compatibility mode, do the following: 如果未在兼容模式下添加引用,请执行以下操作:

Right click on references Add Service Reference-> Advanced -> Add Web Reference (Below the compatibility section), type the URL of the WS and add the reference. 右键单击引用添加服务引用 - >高级 - >添加Web引用(在兼容性部分下面),键入WS的URL并添加引用。

The WSE2.0 extensions are available as a Nuget Package at: WSE2.0扩展可在以下位置以Nuget包的形式提供:

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

Install the nuget package on the package manager console running the following nugget command: Install-Package Microsoft.Web.Services2 在运行以下nugget命令的程序包管理器控制台上安装nuget程序包:Install-Package Microsoft.Web.Services2

After you installed the nuget package, you need to make sure your project is referencing the following DLL's: 安装nuget包后,您需要确保您的项目引用以下DLL:

  1. System.Web 的System.Web
  2. System.Web.Services System.Web.Services
  3. Microsoft.Web.Services2 (This will be added after you install the nuget package) Microsoft.Web.Services2(这将在安装nuget包后添加)

In order to use the WSE2.0 extensions, you need to actually modify the Proxy class that was created when you added the WebReference to inherit from "Microsoft.Web.Services2.WebServicesClientProtocol" instead of "System.Web.Services.Protocols.SoapHttpClientProtocol". 为了使用WSE2.0扩展,您需要实际修改在添加WebReference时从“Microsoft.Web.Services2.WebServicesClientProtocol”而不是“System.Web.Services.Protocols.SoapHttpClientProtocol”继承时创建的Proxy类。 ”。 Be aware that if you update the WebReference, the Proxy class will inherit againfrom SoapHttpClientProtocol. 请注意,如果更新WebReference,Proxy类将再次从SoapHttpClientProtocol继承。

Add the following using clauses to the code consuming the Proxy class: 将以下using子句添加到使用Proxy类的代码中:

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

After you make this changes, you code should look something like this: 进行此更改后,您的代码应如下所示:

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...

I added the screenshot down below for your reference: 我在下面添加了屏幕截图供您参考:

在此输入图像描述

NOTE: I was unable to test the code since I am unfamiliar with the actual methods that you need to consume, the code displayed is just an example of what I saw in the proxy class, update it according to your needs. 注意:我无法测试代码,因为我不熟悉您需要使用的实际方法,显示的代码只是我在代理类中看到的示例,根据您的需要进行更新。 It should work fine if you follow the steps described before. 如果您按照之前描述的步骤操作它应该可以正常工作。 Check the following link for more detailed instructions: 请查看以下链接以获取更多详细说明:

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

You can configure you Service Reference to add the Security Header as AW Rowse describes at http://cxdeveloper.com/article/implementing-ws-security-digest-password-nonce-net-40-wcf : 您可以配置服务引用以添加安全标头,如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())
        );
    }

And create you client/proxy like this: 并创建这样的客户端/代理:

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

The properties you will need to create in your class are: 您需要在班级中创建的属性是:

private BasicHttpBinding defaultBinding;
private UsernameToken defaultToken;
private MessageHeader defaultSecurityHeader;

You won't need to configure anything in app/web.config. 您无需在app / web.config中配置任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM