我正在使用Visual Studio 2010中的WCF编写针对供应商的Web服务的客户端。我无法更改其实现或配置。
在他们的测试服务器上运行安装,我没有遇到任何问题。我从他们的wsdl添加了一个服务引用,在代码中设置了url,并进行了调用:
var client = new TheirWebservicePortTypeClient();
client.Endpoint.Address = new System.ServiceModel.EndpointAddress(webServiceUrl);
if (webServiceUsername != "")
{
client.ClientCredentials.UserName.UserName = webServiceUsername;
client.ClientCredentials.UserName.Password = webServicePassword;
}
TheirWebserviceResponse response = client.TheirOperation(myRequest);
简单明了。直到他们将其移动到生产服务器并将其配置为使用https。然后我收到了这个错误:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm='.
所以我去寻求帮助。我发现了这个:Can not call web service with basic authentication using wcf。
批准的答案表明了这一点:
BasicHttpBinding binding = new BasicHttpBinding();
binding.SendTimeout = TimeSpan.FromSeconds(25);
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
EndpointAddress address = new EndpointAddress(your-url-here);
ChannelFactory<MyService> factory =
new ChannelFactory<MyService>(binding, address);
MyService proxy = factory.CreateChannel();
proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "password";
这似乎也很简单。除了我试图找出从wsdl生成的众多类和接口中的哪一个来制作服务引用之外,我应该使用它代替上面的“MyService”。
我的第一次尝试是使用“TheyWebservicePortTypeClient” - 我在之前版本中实例化的类。这给了我一个运行时错误:
The type argument passed to the generic ChannelFactory class must be an interface type.
所以我深入研究了生成的代码。我看到了这个:
public partial class TheirWebservicePortTypeClient
:
System.ServiceModel.ClientBase<TheirWebservicePortType>,
TheirWebservicePortType
{
...
}
所以我尝试了实例化ChannelFactory&lt;&gt;使用TheirWebservicePortType。
这给了我编译时错误。生成的代理没有ClientCredentials成员或TheyOperation()方法。
所以我尝试了“System.ServiceModel.ClientBase”。
实例化ChannelFactory&lt;&gt;用它仍然给我编译时错误。生成的代理确实有一个ClientCredentials成员,但它仍然没有TheyOperation()方法。
那么,是什么给出的?如何从WCF客户端将用户名/密码传递给HTTPS Web服务?
====================编辑解释解决方案====================
首先,按照建议,使用TheirWebservicePortType实例化工厂,将工具用户名和密码添加到factory.Credentials,而不是代理.ClientCredentials工作正常。除了一点混乱。
也许这与编写wsdl的奇怪方式有关,但客户端类ItsWebservicePortTypeClient将TheirOperation定义为接受Request参数并返回Response结果。 TheyWebservicePortType接口将TheirOperation定义为接受一个TheirOperation_Input参数并返回一个TheirOperation_Output结果,其中TheirOperation_Input包含一个Request成员,而ItsOperation_Output包含一个Response成员。
在任何情况下,如果我从传递的Request构造了一个TheirOperation_Input对象,则对代理的调用成功,然后我可以从返回的TheirOperation_Output对象中提取包含的Response对象:
TheirOperation_Output output = client.TheirOperation(new TheirOperation_Input(request));
TheirWebserviceResponse response = output.TheirWebserviceResponse;
答案 0 :(得分:1)
您将凭据添加到ChannelFactory Credentials属性