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

时间:2017-06-02 15:26:37

标签: c# wcf wcf-security

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

'没有端点正在侦听......可以接受该消息。这通常是由错误的地址或SOAP操作引起的。'

必须仅按代码使用设置!

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

atoi

我尝试了几种解决方法,但似乎没有什么特别像我的。

1 个答案:

答案 0 :(得分:1)

我认为你有几个选择,其中一些我将在下面详述。

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

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

使用第二种方法时,请务必注意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();