我正在使用 WCF 使用 WebService PHP 运行 Visual Studio 2008 单元测试 C#,但收到以下错误:
System.ServiceModel.Security.MessageSecurityException:HTTP 请求未经客户端身份验证方案“匿名”授权。从服务器收到的身份验证标头是“NTLM,Basic realm="(null)"”。---> System.Net.WebException: 远程服务器返回错误: (401) Unauthorized..
我正在使用 Windows XP SP3 机器、单元测试 VS 2008 和 WCF 连接到 PHP WebService。
我无法控制 PHP WebService。我无法修改它(既不是配置安全性)。
这是我使用 web 服务 PHP 的客户端的配置文件:
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="customTextMessageEncoding"
type="COMPANY.IntegracionEasyVista.CustomTextEncoder.CustomTextMessageEncodingElement,COMPANY.IntegracionEasyVista.CustomTextEncoder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9744987c0853bf9e" />
</bindingElementExtensions>
</extensions>
<bindings>
<customBinding>
<binding name="ISO8859Binding">
<customTextMessageEncoding messageVersion="Soap11WSAddressing10"
encoding="ISO-8859-1" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://serverphp/webservice/SmoBridge.php"
binding="customBinding" bindingConfiguration="ISO8859Binding"
contract="ServiceEasyVista.WebServicePortType" name="EasyVistaSvcEndPoint" />
</client>
</system.serviceModel>
真的,我使用 C# 代码:
var endpointAddress = Config.AppSettings.Settings[EasyVistaSvcEndPointAddress].Value;
var endpoint = new System.ServiceModel.EndpointAddress(endpointAddress);
var endpointBinding = new System.ServiceModel.Channels.CustomBinding();
endpointBinding.Name = "ISO8859Binding";
var bindingElement = new IntegracionEasyVista.CustomTextEncoder.CustomTextMessageBindingElement();
bindingElement.Encoding = "ISO-8859-1";
bindingElement.MessageVersion = System.ServiceModel.Channels.MessageVersion.Soap11WSAddressing10; // "Soap11WSAddressing10"
endpointBinding.Elements.Add(bindingElement);
var transportBinding = new HttpTransportBindingElement();
endpointBinding.Elements.Add(transportBinding);
ConfigurarBinding(endpointBinding);
var svcClient = new WebServicePortTypeClient(endpointBinding, endpoint);
return svcClient;
更新:测试
我添加这一行:
transportBinding.AuthenticationScheme = System.Net.AuthenticationSchemes.Negotiate;
我收到此错误:HTTP 请求未经客户端身份验证方案“匿名”授权。从服务器收到的身份验证标头是 'NTLM,Basic realm="(null)"'
我添加这一行:
transportBinding.AuthenticationScheme = System.Net.AuthenticationSchemes.Basic;
我得到这个错误:
System.ServiceModel.CommunicationObjectFaultedException: El objeto de comunicación, System.ServiceModel.Channels.ServiceChannel, no se puede usar para la comunicación porque se encuentra en el estado 故障。
//服务器堆栈跟踪: // en System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
我添加这一行:
transportBinding.AuthenticationScheme = System.Net.AuthenticationSchemes.Ntlm;
我得到这个错误:
/Exception = System.ServiceModel.CommunicationException: Versión de mensaje no reconocida。
//服务器堆栈跟踪: // en System.ServiceModel.Channels.ReceivedMessage.ReadStartEnvelope(XmlDictionaryReader reader)
// en System.ServiceModel.Channels.StreamedMessage..ctor(XmlDictionaryReader reader, Int32 maxSizeOfHeaders, MessageVersion desiredVersion)
// en System.ServiceModel.Channels.Message.CreateMessage(XmlDictionaryReader envelopeReader, Int32 maxSizeOfHeaders, MessageVersion 版本)
// en System.ServiceModel.Channels.Message.CreateMessage(XmlReader envelopeReader, Int32 maxSizeOfHeaders, MessageVersion 版本)
// en CustomTextEncoder.CustomTextMessageEncoder.ReadMessage(Stream stream, Int32 maxSizeOfHeaders, String contentType) en E:\TFS\pro\CustomTextEncoder\CustomTextMessageEncoder.cs:línea 66
// en System.ServiceModel.Channels.MessageEncoder.ReadMessage(Stream stream, Int32 maxSizeOfHeaders)
// en CustomTextEncoder.CustomTextMessageEncoder.ReadMessage (ArraySegment`1 buffer, BufferManager bufferManager, String contentType) en E:\TFS\pro\CustomTextEncoder\CustomTextMessageEncoder.cs:linea 60
// en System.ServiceModel.Channels.MessageEncoder.ReadMessage(Stream stream, BufferManager bufferManager, Int32 maxBufferSize, String contentType)
// zh System.ServiceModel.Channels.HttpInput.ReadChunkedBufferedMessage(Stream inputStream)
我认为,以下是正确的配置(如果是 basichttpbinding)
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
basichttpbinding中WCF的Web服务可能不够灵活。顾名思义,CustomBinding 允许用户设计自己的 Web 服务绑定。
我需要使用CustomBinding和 SecurityMode (like basichttpbinding): WCF BasicHttpBinding equivalent CustomBinding
我需要安全模式:TransportCredentialOnly、Basic、HTTP 传输和编码="ISO-8859-1"
http://www.codemeit.com/security/wcf-basichttpbinding-equivalent-custombinding.html
http://social.msdn.microsoft.com/Forums/en/wcf/thread/6cefadf1-9939-4f3b-a502-2d79a30c7d3a
http://offroadcoder.com/2008/03/23/CallingYourNusoapPHPWebServiceFromWCF.aspx
http://msdn.microsoft.com/en-us/library/ms731092(v=VS.90).aspx
我再次尝试使用此配置,但出现错误:
svcPro.ClientCredentials.UserName.UserName = "MY USER";
svcPro.ClientCredentials.UserName.Password = "XXXX";
配置:
<customBinding>
<binding name="ISO8859Binding">
<customTextMessageEncoding messageVersion="Soap11WSAddressing10" encoding="ISO-8859-1" />
<!--<textMessageEncoding MessageVersion="Soap11" />-->
<!--<httpTransport />-->
<httpTransport authenticationScheme="Basic" />
</binding>
</customBinding>
错误(InnerException 为空):
错误:无法识别的消息版本
类型:System.ServiceModel.CommunicationException Mensaje:Versión de mensaje no reconocida。StackTrace:服务器堆栈跟踪:
zh System.ServiceModel.Channels.ReceivedMessage.ReadStartEnvelope(XmlDictionaryReader 阅读器)
en System.ServiceModel.Channels.StreamedMessage..ctor(XmlDictionaryReader reader, Int32 maxSizeOfHeaders, MessageVersion desiredVersion)
en System.ServiceModel.Channels.Message.CreateMessage(XmlDictionaryReader envelopeReader, Int32 maxSizeOfHeaders, MessageVersion 版本)
en System.ServiceModel.Channels.Message.CreateMessage(XmlReader envelopeReader, Int32 maxSizeOfHeaders, MessageVersion 版本)
en Reale.IntegracionEasyVista.CustomTextEncoder.CustomTextMessageEncoder.ReadMessage(Stream stream, Int32 maxSizeOfHeaders, String contentType) en E:\IntegracionEasyVista\CustomTextEncoder\CustomTextMessageEncoder.cs:línea 66
en System.ServiceModel.Channels.MessageEncoder.ReadMessage(Stream stream, Int32 maxSizeOfHeaders) en Reale.IntegracionEasyVista.CustomTextEncoder.CustomTextMessageEncoder.ReadMessage(ArraySegment`1 buffer, BufferManager bufferManager, String contentType) en E:\IntegracionEasyVista\CustomTextEncoder\CustomTextMessageEncoder.cs :linea 60
en System.ServiceModel.Channels.MessageEncoder.ReadMessage(Stream stream, BufferManager bufferManager, Int32 maxBufferSize, String contentType)
zh System.ServiceModel.Channels.HttpInput.ReadChunkedBufferedMessage(Stream inputStream)
zh System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(Exception& requestException)
zh System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
en System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
en System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
en System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
en System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] out)
en System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime 操作)
zh System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)
更多信息:Service.php 的 WDSL 的一部分
<?xml version="1.0" encoding="ISO-8859-1" ?>
<definitions
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:si="http://soapinterop.org/xsd"
xmlns:tns="http://192.168.110.50/WebService" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://192.168.110.50/WebService">
<types>
<xsd:schema targetNamespace="http://192.168.110.50/WebService">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
</xsd:schema>
</types>