如何在WCF上使用HTTPTransportBindingElement设置代理凭据



我使用httptransportbindingelement与IIS在端口80上结合使用了WCF服务。只要不使用代理,该代码就可以正常工作。但是,如果客户患有http-proxy,那么在这种情况下,wcf-client和服务器之间的通信无法通过以下错误来使用:

'没有端点在...可以接受消息。这通常是由不正确的地址或肥皂作用引起的。'

仅使用代码使用设置!

这是我解决该问题的代码方法,但我坚持下去:

bool SendClientRequest(Action<ICustomerService> channel)
{
  string proxy ="my.proxy.domain:8080";
  string user = "user1";
  string password="secret";
  // maybe i do not need this 3 lines!
  WebProxy webproxy = new WebProxy(proxy, true);
  webproxy.Credentials = new NetworkCredential(user, password);
  WebRequest.DefaultWebProxy = webproxy;
  CustomBinding customBinding = new CustomBinding();
  customBinding.Elements.Add(new HttpTransportBindingElement()
  {
   AuthenticationSchemes.None : AuthenticationSchemes.Basic,                
   ProxyAddress = string.IsNullOrEmpty(proxy) ? null : new Uri(proxy),
   UseDefaultWebProxy = false,
   BypassProxyOnLocal = true,
   TransferMode = TransferMode.Streamed,
   MaxReceivedMessageSize = 84087406592,
   MaxBufferPoolSize = 0x1000000,
   MaxBufferSize = 0x1000000
  });

  using (ChannelFactory<ICustomerService> factory = new  
  ChannelFactory<ICustomerService>(customBinding ))
  {
   IClientChannel contextChannel = null;
   string url = "http://my.domain.de/Distribution/eService.svc", 
   EndpointAddress ep = new EndpointAddress(url);
   ICustomerService clientChannel = factory.CreateChannel(ep);                

   contextChannel = clientChannel as IClientChannel;
   contextChannel.OperationTimeout = TimeSpan.FromMinutes(rcvTimeout );
   channel(clientChannel); // <- here i get the exception!
   return true;
  }
}

我尝试了几种解决方案方法,但似乎没有什么像我的那样具体的。

我认为您有一些选择,其中一些我将在下面进行详细介绍。

首先,您可以将UseDefaultWebProxy设置为true。这将意味着从系统代理设置自动检索代理信息,该设置可在Internet Explorer(Internet选项> Connections> Connections> LAN设置>代理服务器(中配置。如果您不需要为代理使用指定凭据。

另一种对我有用的方法是使用HttpTransportBindingElement()对象中的ProxyAuthenticationScheme属性。此属性仅在CustomBinding类中可用,并且允许指定身份验证方案,该方案将用于对代理进行身份验证。结合使用,必须针对属性ProxyAddress设置代理服务器。最后但并非最不重要的一点是,应根据所使用的身份验证方案设置用于代理的凭据,例如,使用AuthenticationSchemes.Ntlm意味着在ChannelFactory.ClientCredentials.Windows.ClientCredentialChannelFactory.ClientCredentials.HttpDigest.ClientCredential

上设置用户名和密码属性

使用第二种方法,请务必注意在Channelfactory中持有凭据与远程服务与代理服务器使用的凭据之间的差异。我在下面的代码示例中强调了这些,以清楚:

// Example service call using a CustomBinding that is configured for client
// authentication based on a user name and password sent as part of the message.
var binding = new CustomBinding();
TransportSecurityBindingElement securityBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
var secureTransport = new HttpsTransportBindingElement();
secureTransport.UseDefaultWebProxy = false;
secureTransport.ProxyAddress = new Uri("http://some-proxy");
secureTransport.ProxyAuthenticationScheme = AuthenticationSchemes.Ntlm;
binding.Elements.Add(securityBindingElement);
binding.Elements.Add(secureTransport);
var endpointAddress = new EndpointAddress("https://some-service");
var factory = new ChannelFactory<IService>(binding, endpointAddress);
// Credentials for authentication against the remote service
factory.Credentials.UserName.UserName = "serviceUser";
factory.Credentials.UserName.Password = "abc";
// Credentials for authentication against the proxy server
factory.Credentials.Windows.ClientCredential.UserName = "domainuser";
factory.Credentials.Windows.ClientCredential.Password = "xyz";
var client = factory.CreateChannel();
client.CallMethod();

最新更新