【问题标题】:How to setup proxy Credentials using HttpTransportBindingElement on WCF?如何在 WCF 上使用 HttpTransportBindingElement 设置代理凭据?
【发布时间】:2017-06-02 15:26:37
【问题描述】:

我使用 HttpTransportBindingElement 和端口 80 上的 IIS 编写了一个 WCF 服务。 只要不使用代理,代码就可以正常工作。但是,如果客户有一个 http-proxy,则 WCF-Client 和 Server 之间的通信在这种情况下无法正常工作,会出现以下错误:

'没有可以接受消息的端点监听。这通常是由不正确的地址或 SOAP 操作引起的。'

只能通过代码使用设置!

这是我针对该问题的代码方法,但我坚持使用它:

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

我尝试了几种解决方法,但似乎没有什么比我的更具体。

【问题讨论】:

    标签: c# wcf wcf-security


    【解决方案1】:

    我认为您有几个选择,其中一些我将在下面详细说明。

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

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

    对于第二种方法,请务必注意在 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 = "domain\user";
    factory.Credentials.Windows.ClientCredential.Password = "xyz";
    
    var client = factory.CreateChannel();
    client.CallMethod();
    

    【讨论】:

      猜你喜欢
      • 2017-03-22
      • 2010-09-11
      • 2018-12-22
      • 2013-07-31
      • 2017-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      相关资源
      最近更新 更多