WCFTestClient Die HTTP-Anforderung ist mit dem Clientauthentifizierungsschema 'Anonym' nicht autorisiert.

68

Ich habe einen WCF-Dienst erstellt und auf dem Server bereitgestellt. Wenn ich diesen Dienst durchsuche, erhalte ich eine positive Antwort mit der URL? Wsdl. Jetzt versuche ich, den Dienst über den WCF-Testclient zu testen. Es werden die richtigen Metadaten angezeigt. Wenn ich jedoch versuche, eine der Methoden aus dem Dienst aufzurufen, wird eine Ausnahme angezeigt. Hier sind die Fehlerdetails mit Stack-Trace.

Die HTTP-Anforderung ist mit dem Clientauthentifizierungsschema 'Anonym' nicht autorisiert. Der vom Server empfangene Authentifizierungsheader war "Negotiate, NTLM".

Server-Stack-Trace:

at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication (HttpWebRequest-Anforderung, HttpWebResponse-Antwort, WebException responseException, HttpChannelFactory-Factory)
Die HTTP-Anforderung ist mit dem Clientauthentifizierungsschema 'Anonym' nicht autorisiert. Der vom Server empfangene Authentifizierungsheader war "Negotiate, NTLM".

Server-Stack-Trace:

at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication (HttpWebRequest-Anforderung, HttpWebResponse-Antwort, WebException-AntwortException, HttpChannelFactory-Factory)

Kundenbindungen:

<bindings>
    <wsHttpBinding>
        <binding name="WSHttpBinding_IServiceMagicService" 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="None">
                <transport clientCredentialType="Windows" proxyCredentialType="None"
                    realm="" />
                <message clientCredentialType="Windows" negotiateServiceCredential="true"
                    establishSecurityContext="true" />
            </security>
        </binding>
    </wsHttpBinding>
</bindings>

Serverbindungen:

<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_SEOService" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
      </security>
    </binding>
    <binding name="WSHttpServiceMagicBinding" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000"/>
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
        <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

Kundenbereich des Kunden:

<client>
    <endpoint address="http://hydwebd02.solutions.com/GeoService.Saveology.com/ServiceMagicService.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceMagicService"
        contract="IServiceMagicService" name="WSHttpBinding_IServiceMagicService" />
</client>

Abschnitt "Serverdienste":

<services>
    <service behaviorConfiguration="GeoService.Saveology.com.CityStateServiceProviderBehavior"
    name="GeoService.Saveology.com.CityStateServiceProvider">
    <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_SEOService"
        contract="SEO.Common.ServiceContract.ICityStateService" />
    <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
        contract="IMetadataExchange" />
    </service>
    <service behaviorConfiguration="GeoService.Saveology.com.ServiceMagicServiceProviderBehavior"
    name="GeoService.Saveology.com.ServiceMagicServiceProvider">
    <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpServiceMagicBinding" 
        contract="SEO.Common.ServiceContract.IServiceMagicService">
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
    </service>
</services>
user82613
quelle
Was passiert, wenn Sie diese Methoden mit einem echten Client aufrufen?
John Saunders
OK, danke - aber Sie müssen AUCH den Abschnitt <services> des Servers und den Abschnitt <client> des Clients veröffentlichen, damit wir sehen, wie diese Endpunkte eingerichtet sind und wie Sie sie aufrufen ......
marc_s
Mit einem echten Client funktioniert es ohne ein einziges Problem.
user82613
Ich habe auch den Abschnitt <client> des Clients und den Abschnitt <services> des dn-Servers veröffentlicht.
user82613
1
Es ist symptomatisch für die .Net-Welt, dass Sie so viele (gültige) unterschiedliche Antworten auf dieselbe Frage erhalten und nicht eine einzige, die erklärt, auf welche Parameter Sie sich ändern und warum. Versteht jemand, was er / sie tut?
Thibault D.

Antworten:

83

Ich hatte keine Kontrolle über die Sicherheitskonfiguration für den Dienst, den ich anrief, bekam aber den gleichen Fehler. Ich konnte meinen Client wie folgt reparieren.

  1. Richten Sie in der Konfiguration den Sicherheitsmodus ein:

    <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>
    
  2. Stellen Sie im Code die Proxy-Klasse so ein, dass ein Identitätswechsel möglich ist (ich habe einen Verweis auf einen Dienst namens "Kunde" hinzugefügt):

    Customer_PortClient proxy = new Customer_PortClient();
    proxy.ClientCredentials.Windows.AllowedImpersonationLevel =    
             System.Security.Principal.TokenImpersonationLevel.Impersonation;
    
Alex Peck
quelle
2
Wenn Sie dies programmgesteuert tun, stellen Sie sicher, dass Sie Dim-Bindung als neues System.ServiceModel.BasicHttpBinding () anstelle von Dim-Bindung als neues System.ServiceModel.WSHttpBinding () verwenden
Stefan Steiger
2
Ich weiß wirklich nicht, was ein Customer_PortClient ist, aber das Einstellen des Sicherheitsmodus hat mir geholfen.
Nathan
2
Bei Verwendung <security mode="TransportCredentialOnly">scheint es, dass Sie keine Konfiguration für die Nachrichtensicherheit einschließen müssen. Die SOAP-Nachricht wird unverschlüsselt im Klartext gesendet. Das <message>Tag scheint ignoriert zu werden, damit es keinen Schaden anrichtet, es wird einfach nicht benötigt. Quelle: msdn.microsoft.com/en-us/library/ff648505.aspx
Ben Cottrell
Wo ist "die Konfiguration"? Ich bin ein bisschen neu. EDIT: nvmd hat es von hier herausgefunden: docs.microsoft.com/en-us/dotnet/framework/wcf/…
Crhistian Ramirez
13

Ich habe ein ähnliches Problem, haben Sie versucht:

proxy.ClientCredentials.Windows.AllowedImpersonationLevel =   
          System.Security.Principal.TokenImpersonationLevel.Impersonation;
RailRhoad
quelle
10

Eine andere mögliche Lösung für diesen Fehler, den ich gefunden habe. Möglicherweise haben Sie die genaue Frage von OP nicht beantwortet, können aber anderen helfen, die über diese Fehlermeldung stolpern.

Ich habe meinen Client mit WebHttpBinding im Code erstellt, um die folgende Zeile zu replizieren:

<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>

Ich musste es tun:

var binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
                binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Windows;

sowie Einstellung proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

Wilco
quelle
7

Ich sehe, dass dies noch nicht beantwortet wurde, dies ist ein genaues Zitat von hier :

WSHttpBinding versucht, eine interne Aushandlung auf der SSP-Ebene durchzuführen. Damit dies erfolgreich ist, müssen Sie anonym in IIS für den VDir zulassen. WCF führt dann standardmäßig ein SPNEGO für Fensteranmeldeinformationen aus. Wenn Sie auf der IIS-Ebene anonym zulassen, wird niemand zugelassen, sondern der WCF-Stapel wird verschoben.

Ich fand dies über: http://fczaja.blogspot.com/2009/10/http-request-is-unauthorized-with.html

Nach dem Googeln: http://www.google.tt/#hl=de&source=hp&q=+The+HTTP+request+ist+unauthorized+with+client+authentication+scheme+%27Anonymous

Irwin
quelle
Hallo @Irwin, Danke für die Antwort. Könnten Sie bitte einem Prüfer eine "offiziellere" Quelle wie die von Microsoft erstellte Originaldokumentation zur Verfügung stellen, damit ich dies begründen kann? VIELEN DANK!! Marcelo
Marcelo Finki
5

Ich hatte ein ähnliches Problem und versuchte alles, was oben vorgeschlagen wurde. Dann habe ich versucht, den clientCreditialType in Basic zu ändern, und alles hat gut funktioniert.

<basicHttpBinding>
    <binding name="BINDINGNAMEGOESHERE" >
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic"></transport>
      </security>
    </binding>
  </basicHttpBinding>
PunkTurnet
quelle
3

Hier ist, was ich tun musste, um dies zum Laufen zu bringen. Das heisst:

  1. Benutzerdefinierter UserNamePasswordValidator (kein Windows-Konto, SQLServer oder ActiveDirectory erforderlich - Ihr UserNamePasswordValidator kann Benutzername und Kennwort fest codiert haben oder aus einer Textdatei, MySQL oder was auch immer gelesen werden).
  2. https
  3. IIS7
  4. .net 4.0

Meine Website wird über DotNetPanel verwaltet. Es gibt 3 Sicherheitsoptionen für virtuelle Verzeichnisse:

  1. Anonymen Zugriff zulassen
  2. Aktivieren Sie die Standardauthentifizierung
  3. Aktivieren Sie die integrierte Windows-Authentifizierung

Es wird nur "Anonymen Zugriff zulassen" benötigt (obwohl dies allein nicht ausreichte).

Rahmen

proxy.ClientCredentials.Windows.AllowedImpersonationLevel =  System.Security.Principal.TokenImpersonationLevel.Impersonation;

Hat in meinem Fall keinen Unterschied gemacht.

Die Verwendung dieser Bindung funktionierte jedoch:

      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Windows" />
        <message clientCredentialType="UserName" />
      </security>        
Jimmy
quelle
1

Versuchen Sie, Ihrem Kunden einen Benutzernamen und ein Passwort wie unten anzugeben

client.ClientCredentials.UserName.UserName = @ "Domain \ username"; client.ClientCredentials.UserName.Password = "password";

user2659865
quelle
1

Ich hatte heute den gleichen Fehler, nachdem ich unseren Dienst bereitgestellt hatte, der einen externen Dienst in der Staging-Umgebung in Azure aufrief. Lokal rief der Dienst den externen Dienst ohne Fehler auf, nach der Bereitstellung jedoch nicht.

Am Ende stellte sich heraus, dass der externe Dienst eine IP-Validierung hat. Die neue Umgebung in Azure verfügt über eine andere IP-Adresse und wurde abgelehnt.

Wenn Sie also jemals diesen Fehler erhalten, rufen Sie externe Dienste auf

Dies kann eine IP-Einschränkung sein.

rfcdejong
quelle
0

Ich habe dieses Problem gerade auf einer Entwicklungsmaschine (die Produktion funktioniert einwandfrei). Ich ändere meine Konfiguration in IIS, um anonymen Zugriff zu ermöglichen, und gebe meinen Namen und mein Passwort als Anmeldeinformationen ein.

Ich bin mir nicht sicher, aber es funktioniert zu Testzwecken.

David Brunelle
quelle
Können Sie bitte das Code-Snippet dafür hier teilen?
Spidis Web
Ich werde versuchen, es zu finden, aber dieser Beitrag ist von vor 7 Jahren, also weiß ich nicht, ob ich es finden werde ...
David Brunelle
0

Ich hatte auch diesen Fehler und schließlich funktionierten diese Codes für mich in Dot Net Core 3.1

Installieren Sie zuerst svcutil in der Eingabeaufforderung: dotnet tool install --global dotnet-svcutil

Dann schließen Eingabeaufforderung , und öffnen Sie es erneut.

Erstellen Sie dann die Referenz.cs in der Eingabeaufforderung:

dotnet-svcutil http://YourService.com/SayHello.svc

(Es benötigt eine Eingabetaste sowie Benutzername und Passwort)

Fügen Sie dem Projektstamm einen Ordner mit dem Namen Connected Services hinzu .

Kopieren Sie die Datei Reference.cs in den Ordner Connected Services.

Fügen Sie diese 4 Zeilen zu Reference.cs hinzu, nachdem Sie BasicHttpBinding erstellt und MaxBufferSize festgelegt haben:

result.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
result.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
result.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

Verwenden Sie diesen Dienst in Ihrem Controller:

public async Task<string> Get()
    {
        try
        {
            var client = new EstelamClient();
            client.ClientCredentials.UserName.UserName = "YourUserName";
            client.ClientCredentials.UserName.Password = "YourPassword";
            var res = await client.EmployeeCheckAsync("service parameters");
            return res.ToString();
        }
        catch (Exception ex)
        {
            return ex.Message + " ************ stack : " + ex.StackTrace;
        }

    }

Vergessen Sie nicht, diese Pakete in .cshtml zu installieren:

<PackageReference Include="System.ServiceModel.Duplex" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.Http" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.Security" Version="4.6.*" />
M Komaei
quelle