在C#中以编程方式创建WCF客户端的标头(wsse)部分 [英] Creating Headers (wsse) Section of WCF Client Programmatically in C#

查看:80
本文介绍了在C#中以编程方式创建WCF客户端的标头(wsse)部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何以编程方式在C#中进行app.config服务设置的以下部分:

how do make a the following section of Service Settings of app.config in C# programmatically:

    <client>
  <endpoint address="https://someServiceUrl"
      binding="basicHttpBinding" bindingConfiguration="Contact"
      contract="ServiceReference.PostingWebService" name="PostingWebServicePort">
    <headers>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:UsernameToken>
          <wsse:Username>someusername</wsse:Username>
          <wsse:Password Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'>somepassword</wsse:Password>
        </wsse:UsernameToken>
      </wsse:Security>
    </headers>
  </endpoint>
</client>

我设法从C#生成绑定部分(上面未包括)和端点部分。我无法创建标题部分。

I have managed to generate binding section (not included above) and endpoint section from C#. I am unable to create the headers section.

出现的错误是:(这是因为从C#生成所有内容时我没有标题部分)

The error that comes up is: (this is because I don't have headers section when I generate everything from C#)

此服务需要< wsse:Security> ,该服务会丢失。

This service requires <wsse:Security>, which is missing.

标头部分很重要,好像我将其从配置中排除并使用config运行代码一样,也会出现上述错误。

the headers section is important, as if I exclude it from the config and run the code using config it also gives the above error.

我不想使用web.config / app.config。我必须从C#运行所有程序。 (上面的app.config可以正常工作,但我想通过C#进行同样的操作)

I don't want to use web.config/app.config. I have to run every thing from C#. (the above app.config works fine, but I want to do that same through C#)

更新1 :(首先以编程方式使用BasicHttpBinding)

UPDATE 1: (programmatically using BasicHttpBinding first)

BasicHttpBinding binding = new BasicHttpBinding();
        binding.Name = "Contact";
        binding.CloseTimeout = TimeSpan.FromMinutes(1);
        binding.OpenTimeout = TimeSpan.FromMinutes(1);
        binding.ReceiveTimeout = TimeSpan.FromMinutes(10);
        binding.SendTimeout = TimeSpan.FromMinutes(1);
        binding.AllowCookies = false;
        binding.BypassProxyOnLocal = false;
        binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
        binding.MaxBufferSize = 524288;
        binding.MaxBufferPoolSize = 524288;
        binding.MaxReceivedMessageSize = 524288;
        binding.MessageEncoding = WSMessageEncoding.Text;
        binding.TextEncoding = System.Text.Encoding.UTF8;
        binding.TransferMode = TransferMode.Buffered;
        binding.UseDefaultWebProxy = true;

        binding.ReaderQuotas.MaxDepth = 32;
        binding.ReaderQuotas.MaxStringContentLength = 65536;
        binding.ReaderQuotas.MaxArrayLength = 131072;
        binding.ReaderQuotas.MaxBytesPerRead = 32768;
        binding.ReaderQuotas.MaxNameTableCharCount = 131072;

        binding.Security.Mode = BasicHttpSecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
        binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
        binding.Security.Transport.Realm = "";
        binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
        binding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Default;

        CustomBinding customBinding = new CustomBinding(binding);
        SecurityBindingElement element = customBinding.Elements.Find<SecurityBindingElement>();
        // Remove security timestamp because it is not used by your original binding
        //element.IncludeTimestamp = false; (element is NULL in my case)

EndpointAddress endpoint = new EndpointAddress("https://myserviceaddress");

        PostingWebServiceClient client = new PostingWebServiceClient(customBinding, endpoint);

        client.ClientCredentials.UserName.UserName = "myusername";
        client.ClientCredentials.UserName.Password = "mypassword";

        client.getActiveChannels(new getActiveChannels());






直接使用自定义Bindgin:


Using Custom Bindgin Directly:

SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
        securityElement.IncludeTimestamp = false;
        TextMessageEncodingBindingElement encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
        HttpsTransportBindingElement transportElement = new HttpsTransportBindingElement();

        CustomBinding customBinding = new CustomBinding(securityElement, encodingElement, transportElement);


EndpointAddress endpoint = new EndpointAddress("https://myserviceaddress");

        PostingWebServiceClient client = new PostingWebServiceClient(customBinding, endpoint);

        client.ClientCredentials.UserName.UserName = "myusername";
        client.ClientCredentials.UserName.Password = "mypassword";

        client.getActiveChannels(new getActiveChannels());


推荐答案

您不必在此直接配置标头之所以这样,是因为您的方案应直接由 BasicHttpBinding CustomBinding 支持。

You don't have to configure header directly in this case because your scenario should be supported by BasicHttpBinding or CustomBinding directly.

如果需要从C#配置它,则必须在代码中创建绑定:

If you need to configure it from C# you must create binding in code:

// Helper binding to have transport security with user name token
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
// Rest of your binding configuration comes here

// Custom binding to have access to more configuration details of basic binding
CustomBinding customBinding = new CustomBinding(binding);
SecurityBindingElement element = customBinding.Elements.Find<SecurityBindingElement>();
// Remove security timestamp because it is not used by your original binding
element.IncludeTimestamp = false;

EndpointAddress address = new EndpointAddress("https://...");

ProxyWebServiceClient client = new ProxyWebServiceClient(customBinding, address);
client.ClientCredentials.UserName.UserName = "...";
client.ClientCredentials.UserName.Password = "...";

其他解决方案是直接构建自定义绑定,而不是从基本绑定开始:

Other solution is building custom binding directly instead of starting with basic binding:

SecurityBindingElemetn securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityElement.IncludeTimestamp = false; 
TextMessageEncodingBindingElement encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
HttpsTransportBindingElement tranportElement = new HttpsTransportBindingElement();

// Other configurations of basic binding are divided into properties of 
// encoding and transport elements

CustomBinding customBinding = new CustomBinding(securityElement, encodingElement, transportElement);

EndpointAddress address = new EndpointAddress("https://...");

ProxyWebServiceClient client = new ProxyWebServiceClient(customBinding, address);
client.ClientCredentials.UserName.UserName = "...";
client.ClientCredentials.UserName.Password = "...";

这篇关于在C#中以编程方式创建WCF客户端的标头(wsse)部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆