通过WCF调用第三方安全Web服务 - 身份验证问题

时间:2012-08-02 23:11:47

标签: wcf https

我正在使用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;

1 个答案:

答案 0 :(得分:1)

您将凭据添加到ChannelFactory Credentials属性