使用WCF ChannelBase的HTTP代理基本身份验证

时间:2011-07-04 12:11:21

标签: wcf authentication proxy wcf-client

我遇到了基本身份验证问题,无法连接在Visual Studio中从ChannelBase派生的Web服务。已经尝试在MSDN中询问没有结果,所以我在这里试试运气。

这是情景:

a)Web服务需要基本身份验证(用户名和密码)并支持SOAP 1.1

b)我必须通过HTTP代理,再次需要基本身份验证。

我无法使用此功能:Web服务上的身份验证很好(如果绕过代理进行测试)但看起来我无法配置ChannelBase派生类来处理代理上的身份验证(在获得身份验证之后) HTTP响应它不会继续协商身份验证。)

这是我在app.config中的当前设置

<configuration>
 <system.serviceModel>
  <bindings>
   <customBinding>
    <binding name="LocationWSBinding" receiveTimeout="00:02:30">
     <textMessageEncoding messageVersion="Soap11" />
     <httpTransport authenticationScheme="Basic" proxyAddress="http://The.proxy.ip" useDefaultWebProxy="false" 
      bypassProxyOnLocal="True" proxyAuthenticationScheme="Basic" />
    </binding>
   </customBinding>
  </bindings>
  <client>
   <endpoint address="http://the.web.service"
      binding ="customBinding" bindingConfiguration="LocationWSBinding"
     contract="The.Contract.Name" name="LocationWSPort" />
  </client>
 </system.serviceModel>
</configuration>

在代码中,这是我指定凭据的地方:

TheClient WS = new TheClient(“LocationWSPort”);

  WS.ClientCredentials.UserName.UserName = "WebServiceUsername";
  WS.ClientCredentials.UserName.Password = "WebServicepassword";
  WS.ChannelFactory.Credentials.Windows.ClientCredential = new NetworkCredential("Proxyusername","ProxyPassword");

你能帮帮我吗?

我不知道阻止客户端在请求时继续进行代理身份验证有什么问题。

谢谢Emanuele


恩里科,对不起,迟到了。 我已经尝试过你的建议了,只有当我调用一个不需要参数的webservice方法时才会工作,当我调用一个需要复杂类型作为参数的方法时(这是我必须做的真正的调用以获得有用的有效负载)我得到以下内容错误:

{"The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."}
[System.ServiceModel.CommunicationException]: {"The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."}
_className: null
_data: {System.Collections.ListDictionaryInternal}
_dynamicMethods: null
_exceptionMethod: null
_exceptionMethodString: null
_helpURL: null
_HResult: -2146233087
_innerException: null
_ipForWatsonBuckets: 83189596
_message: "The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."
_remoteStackIndex: 1
_remoteStackTraceString: "\r\nServer stack trace: \r\n   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)\r\n   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)\r\n   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)\r\n\r\nException rethrown at [0]: \r\n"
_safeSerializationManager: {System.Runtime.Serialization.SafeSerializationManager}
_source: null
_stackTrace: {sbyte[80]}
_stackTraceString: null
_watsonBuckets: null
_xcode: -532462766
_xptrs: 0
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146233087
InnerException: null
IsTransient: false
Message: "The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."
Source: "mscorlib"
StackTrace: "\r\nServer stack trace: \r\n   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)\r\n   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)\r\n   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)\r\n\r\nException rethrown at [0]: \r\n   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)\r\n   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)\r\n   at [.......] in E:\\VisualStudioPrj\\HTTPproxyTroubleshoot\\HTTPproxyTroubleshoot\\Program.cs:line 88"
TargetSite: {Void HandleReturnMessage(System.Runtime.Remoting.Messaging.IMessage, System.Runtime.Remoting.Messaging.IMessage)}

现在,我确信数据合同是正常的(如果我没有设置WebRequest.DefaultWebProxy,它会正常工作)。 至于FTP,这些SOAP调用是由Windows服务运行的两个线程中的一个完成的,它们协调它们:另一个是处理FTP调用,我需要这些不通过代理转换,否则回答将被格式化为HTML,这扰乱了FTP通信...

1 个答案:

答案 0 :(得分:3)

您遇到的问题是由WCF will use the same set of client credentials both for service authentication and for upstream web proxy authentication引起的。由于您的服务需要与上游Web代理不同的凭据对,因此请求未经过正确身份验证,随后会被阻止。

由于您只能在ClientCredentials类上指定一组凭据,因此解决方案是设置凭据以便在较低级别使用Web代理,使用{ {3}}属性。

以下是一个例子:

var webProxy = new WebProxy
{
    Address = "http://myproxy:8080",
    Credentials = new NetworkCredential("username", "password")
};

WebRequest.DefaultWebProxy = webProxy;

然后,您应该告诉WCF使用刚刚通过WebRequest.DefaultWebProxy类配置的默认代理:

<bindings>
    <customBinding>
        <binding name="MyBinding">
            <textMessageEncoding messageVersion="Soap11" />
            <httpTransport authenticationScheme="Basic"
                           useDefaultWebProxy="true" 
                           bypassProxyOnLocal="true"
                           proxyAuthenticationScheme="Basic" />
        </binding>
    </customBinding>
</bindings>

相关资源: