WCF可以使用https访问SOAP 1.1服务吗?

时间:2015-03-07 13:42:07

标签: c# php wcf authentication soap

我有一个需要与C#应用程序交谈的SOAP服务。我有一个PHP测试应用程序,它使用标准的SoapClient来使用相同的SOAP服务。

它的使用类似于:

$options = array(
    'login' => $username,
    'password' => $password,
    'location' => "https://$serveruri/soap",
);

$service = new SOAPClient($wsdl, $options);

$retval = $service->SomeMethod($parameter);

这很好用。据我所知(我在PHP上没用),因为我们没有设置身份验证选项,所以应该使用基本身份验证。

我正在尝试与C#中的同一端点进行通信,并且它一直提示我进行身份验证。我不知道如何重新创建相同的身份验证。我相信一些问题来自于使用https - 我过去能够使用http和BasicHttpBinding与类似的系统进行交谈,但由于我必须通过https与这个系统进行对话,这是不行的。

所以我使用SvcUtil生成了一个客户端代理,我正在尝试与之交谈。这是我目前的绝望迭代:

var endpoint = new EndpointAddress(SoapUrl);

var binding = new WSHttpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.SendTimeout = new TimeSpan(0, 0, 10);

ServicePointManager.ServerCertificateValidationCallback +=
                (sender, cert, chain, sslPolicyErrors) => true;

var client = new soapServiceClient(binding, endpoint);

if (client.ClientCredentials != null)
{
   client.ClientCredentials.UserName.UserName = Settings.AuthenticationUsername;
   client.ClientCredentials.UserName.Password = Settings.AuthenticationPassword;
}

var retval = client.SomeMethod(parameter);

并解决Jons的评论如下:client.ClientCredentials在我运行时确实不是null。 ReSharper把它放在那里以阻止自己唠叨。

当我运行时,我从服务器获得401 Unauthorized。我在Visual Studio 2013中获得以下内容:

附加信息:HTTP请求未经授权,客户端身份验证方案为“基本”。从服务器收到的身份验证标头是'Basic realm =“bla bla service”'。

在这种情况下,如何让WCF像PHPs SOAPClient一样?

我应该使用另一种绑定吗?我尝试过不同的SecurityMode值,我尝试过Digest身份验证,但是他们让我无处可去。由于这发生在https上,我想我无法将Wireshark发生..

感谢任何见解!

编辑:Jon建议尝试Fiddler2。我打开了https解密并试一试。

有两件事突然袭来我:

1)当我在本地运行PHP脚本(使用在我的机器上运行的EasyPHP)时,它会联系SOAP服务器并获取数据。但是,Fiddler2没有以任何方式看到这种流量。

2)当我在Visual Studio 2013中运行我的应用程序时,Fiddler2 看到流量,并对其进行解密。我看到两次尝试联系SOAP端点;两者都获得401回复。第一个没有auth信息(查看Inspectors - > Fiddler2的Auth部分)并且只是说:

没有代理授权标头。

没有授权标题。

然后第二个请求尝试使用看起来像这样的Authorization标头修复它:

授权标题存在:基本[一些哈希数据] 解码用户名:密码= [正确用户名]:[正确密码]

但如上所述 - 这仍然引发了另一方的401。

我不知道为什么PHP流量不会出现在Fiddler2中,但它非常清楚地从另一方接收实时数据。也许PHP不会以Fiddler2可以接收的方式使用网络堆栈,我不知道。

编辑2 :在PHP端进行了一系列肮脏的调试后,我终于将PHP应用程序的请求/响应周期与WCF进行了比较。这让我更加接近(不知何故,我在auth用户名中得到了一个子字符,这导致了身份验证问题),但现在我正在努力解决由于我的绑定被设置为Content-Type application / soap + xml引起的ProtocolException和外部服务(我相信这是基于Linux的)返回text / xml。

我对滥用Google的理解是,text / xml在SOAP 1.1中很常见,而application / soap + xml与SOAP 1.2一起使用。

另外,据我所知,在WCF中,BasicHttpBinding支持SOAP 1.1,而WsHttpBinding支持SOAP 1.2。

由于此服务位于公共互联网上,因此安全性需要https。我相信系统本身的原始SOAP服务使用HTTP,但它位于需要HTTPS的网关后面,然后将其作为HTTP传递给服务请求的实际框。

问题的核心是:我有办法使用带有WCF的HTTPS访问SOAP 1.1服务吗?

1 个答案:

答案 0 :(得分:2)

所以我已经完成了这个问题。我今天早上作为WCF新手开始,虽然我甚至声称自己是一个称职的用户,但我对绑定有了更多了解。

通过使用鸟枪调试,我实际上已经正确地完成了几次,但是我被我复制到我的代码中的用户名中的一个看不见的子角色(^ Z我相信)欺骗了。

此外,由于我看到很多关于BasicHttpBinding不支持https的信息,这种情况更加复杂 - 如果您按照这样创建它,它会这样做:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);

相信这篇相对较旧的文章,教育我将其弄清楚:

https://msdn.microsoft.com/en-us/magazine/cc163394.aspx

从这篇文章中我也了解到BasicHttpBinding不支持https,我可以构建自己的CustomBinding,只需相对较少的努力即可。

还要感谢我们的霸主Jon Skeet让我朝着正确的方向努力,弄清楚实际上是通过电线发送的是什么!