(401) Несанкционированная ошибка: безопасность / привязка WCF - PullRequest
7 голосов
/ 05 февраля 2010

У меня есть веб-сервис WCF и клиент на одном компьютере. Доступ к веб-службе WCF напрямую через браузер работает, но клиент не может подключиться; сообщение об ошибке ниже. Есть идеи? Встроенная проверка подлинности Windows в IIS используется как для клиента, так и для сервера.

The remote server returned an error: (401) Unauthorized. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Net.WebException: The remote server returned an error: (401) Unauthorized.

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.  

Stack Trace: 

[WebException: The remote server returned an error: (401) Unauthorized.]
   System.Net.HttpWebRequest.GetResponse() +5313085
   System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +54

[MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +7594687
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +275
   HRPaysService.IService1.GetAlert() +0
   HRPaysService.Service1Client.GetAlert() +15
   _Default.Page_Load(Object sender, EventArgs e) +138
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +50
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

Клиент:

  <system.serviceModel>
     <bindings> 
        <basicHttpBinding> 
           <binding name="basicBinding"> 
              <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Windows" 
                             proxyCredentialType="Windows" realm="" />
                  <message clientCredentialType="UserName" 
                           algorithmSuite="Default" />
              </security> 
           </binding> 
        </basicHttpBinding> 
     </bindings> 
     <client>
         <endpoint 
             address="http://hrpaysservice/service1.svc" 
             binding="basicHttpBinding"
             bindingConfiguration="basicBinding" 
             contract="HRPaysService.IService1">
         </endpoint>
     </client>
  </system.serviceModel>

Сервер:

<system.serviceModel>
   <bindings> 
      <basicHttpBinding> 
         <binding name="basicBinding"> 
            <security mode="TransportCredentialOnly">
                <transport clientCredentialType="Windows" 
                           proxyCredentialType="Windows" realm="" />
                <message clientCredentialType="UserName" 
                         algorithmSuite="Default" />
            </security> 
         </binding> 
      </basicHttpBinding> 
   </bindings> 
   <client>
       <endpoint 
           address="http://hrpaysservice/service1.svc" 
           binding="basicHttpBinding"
           bindingConfiguration="basicBinding" 
           contract="HRPaysService.IService1">
       </endpoint>
</client>
</system.serviceModel>

Ответы [ 4 ]

4 голосов
/ 24 декабря 2012

Я столкнулся с той же ошибкой, когда пытался получить доступ к службе WCF, размещенной в IIS, добавив «1001 * Справочник по услуге » в свое приложение Windows Forms. Но когда клиент нажал на вызов метода службы, я получил «UnAuthorized 401 исключение». Вот мое решение этой проблемы:

(1) Я использовал [wsHttpBinding], измените его на [basicHttpBinding], как указано ниже в файле конфигурации службы WCF:

    <system.serviceModel>
      <bindings>
          <basicHttpBinding>
              <binding name="BasicHttpEndpointBinding">
                  <security mode="TransportCredentialOnly">
                      <transport clientCredentialType="Windows" />
                  </security>
              </binding>
          </basicHttpBinding>
      </bindings>
      <services>
      <service behaviorConfiguration="ServiceBehavior"   name="IService1">
          <endpoint address="" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpEndpointBinding"
            name="BasicHttpEndpoint" contract="IService1">
              <identity>
                  <dns value="localhost" />
              </identity>
          </endpoint>
          <endpoint address="mex" binding="mexHttpBinding"
              contract="IMetadataExchange" />
      </service>
  </services>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
    multipleSiteBindingsEnabled="true" />

(2) Добавьте «Service Reference» из вашего клиентского приложения и дайте ему имя (мы будем использовать это имя на следующем шаге как «ProxyCalssName»)

(3) измените файл app.config клиентского приложения следующим образом:

<system.serviceModel>
    <client>
        <endpoint address="your service URL"
            binding="basicHttpBinding" bindingConfiguration="basic" contract="ProxyClassName.ServiceName"
            name="default" />
    </client>
    <bindings>
        <basicHttpBinding>
            <binding name="basic">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
</system.serviceModel>

(4) В коде клиентского приложения:

        ProxyClassName.MyServiceName srv = new ProxyClassName.MyServiceName("default");
 //default is the name of the endpoint in the app.config file as we did.
    srv.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

Удачи, DigitalFox

1 голос
/ 05 февраля 2010

Клиент:

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
                <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                     bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
                    textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
                        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                        <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:3097/Service1.svc" binding="wsHttpBinding"
            bindingConfiguration="WSHttpBinding_IService1" contract="HRPaysService.IService1"
            name="WSHttpBinding_IService1">
                <identity>
                    <dns value="localhost" />
                </identity>
        </endpoint>
    </client>
</system.serviceModel>

Сервер:

    <system.serviceModel>
        <bindings> 
        <basicHttpBinding> 
                    <binding name="basicBinding"> 
                    <security mode="TransportCredentialOnly"> 
                            <transport clientCredentialType="Windows"/> 
                    </security> 
                </binding> 
            </basicHttpBinding> 
        </bindings> 
    <services>
            <service behaviorConfiguration="basicBehavior" name="WcfService1.Service1"> 
                <endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="basicBinding" /> 
                <endpoint address="mex" binding="basicHttpBinding" contract="IMetadataExchange" bindingConfiguration="basicBinding" /> 
        </service>
    </services>
    <behaviors> 
            <serviceBehaviors> 
                <behavior name="basicBehavior"> 
                    <serviceMetadata httpGetEnabled="true" /> 
                </behavior> 
            </serviceBehaviors> 
        </behaviors> 
</system.serviceModel>

0 голосов
/ 11 февраля 2010

Если виртуальный каталог служб WCF не настроен для анонимного доступа, то конечную точку "mex" в необходимо удалить.

Вы опубликовали 2 разных набора конфигов, и, кажется, они не совпадают. Не могли бы вы опубликовать конфиги, которые вызывают ошибку?

Ваша первая (самая верхняя) конфигурация клиента и последняя конфигурация сервера (без части mex) должны работать.

0 голосов
/ 05 февраля 2010

У вас есть документ CrossDomain.xml, настроенный в вашем веб-приложении? Если нет, создайте его со следующим содержимым -

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
    <allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
...