Базовая аутентификация HTTP прокси с WCF ChannelBase - PullRequest
1 голос
/ 04 июля 2011

Я застрял с проблемой базовой аутентификации для подключения веб-службы, которая была создана в Visual Studio и основана на ChannelBase.Уже пытался спросить в MSDN безрезультатно, поэтому я пытаюсь здесь попытаться.

Это сценарий:

a) веб-сервис требует базовой аутентификации (имя пользователя и пароль)и поддерживает SOAP 1.1

b) Мне нужно пройти через HTTP-прокси, который требует, опять же, базовой аутентификации.

Я не могу заставить это работать: аутентификация на веб-сервисе в порядке (если тестирование выполняется в обход прокси-сервера), но похоже, что я не могу настроить производный от 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");

Можете ли вы помочь мне?

Я не знаю, что не так, что блокирует клиента для продолжения аутентификации проксиНа запрос.

Спасибо, Эмануэле


Энрико, извините за поздний ответ.Я попытался следовать вашему предложению, и это работает, только если я вызываю метод веб-сервиса без аргументов, когда я вызываю метод, требующий сложных типов в качестве аргумента (это реальный вызов, который я должен сделать, чтобы получить полезную полезную нагрузку), я получаю следующееошибка:

{"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 Ответ

3 голосов
/ 04 июля 2011

Проблема, с которой вы столкнулись, связана с тем, что WCF будет использовать один и тот же набор учетных данных клиента как для проверки подлинности службы, так и для исходящей проверки подлинности веб-прокси .Поскольку вашей службе требуется пара учетных данных, отличная от той, которую использует ваш прокси-сервер верхнего уровня , запрос не проходит надлежащую проверку подлинности и впоследствии блокируется.

Поскольку вы можете указать только один набор учетных данныхв классе ClientCredentials решение состоит в том, чтобы установить учетные данные для использования с веб-прокси на более низком уровне , используя свойство WebRequest.DefaultWebProxy .

Вот пример:

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

WebRequest.DefaultWebProxy = webProxy;

Затем вы должны указать WCF использовать прокси-сервер по умолчанию, который был только что настроен с помощью класса WebProxy :

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

Связанные ресурсы:

...