Laden...

[erledigt] WCF Service mit wsHttpBinding auf Windows Server 2008

Erstellt von T-Man vor 12 Jahren Letzter Beitrag vor 12 Jahren 6.555 Views
T
T-Man Themenstarter:in
210 Beiträge seit 2006
vor 12 Jahren
[erledigt] WCF Service mit wsHttpBinding auf Windows Server 2008

Moin zusammen,

ich habe einen WCF Service mit zwei Schnittstellen.
Eine ungesicherte Basisschnittstelle mit einfachem basicHttpBinding
Und eine gesicherte Schnittstelle mit wsHttpBinding

Hier die web.config des Servers:


<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicBinding" />
      </basicHttpBinding>
      <wsHttpBinding>
        <binding name="wsHttpBinding">
          <security>
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="amagnoBehavior" name="Amagno.AmagnoService.AmagnoService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding"
          name="wsHttp" contract="Amagno.ExternalServiceContracts.IAmagnoService" />
        <endpoint address="/Basic" binding="basicHttpBinding" bindingConfiguration="BasicBinding"
          name="Basic" contract="Amagno.ExternalServiceContracts.IAmagnoBasicService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="amagnoBehavior">
          <serviceCredentials>
            <serviceCertificate storeName="My" storeLocation="LocalMachine" findValue="CN=test.amagno.org" />
            <userNameAuthentication userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="Amagno.Base.AmagnoUserNamePasswordValidator, AmagnoBase" />
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <appSettings>
...
  </appSettings>

</configuration>

Und nun die app.config des Clients:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <endpointBehaviors>
                <behavior name="wsHttpBehavior">
                    <clientCredentials>
                        <serviceCertificate>
                            <authentication certificateValidationMode="None" revocationMode="NoCheck" />
                        </serviceCertificate>
                    </clientCredentials>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="Basic" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="268435456" maxBufferPoolSize="524288" maxReceivedMessageSize="268435456"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="268435456"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
            <wsHttpBinding>
                <binding name="wsHttp" 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="268435456"
                    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="UserName" negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/AmagnoService/AmagnoService.svc"
                behaviorConfiguration="wsHttpBehavior" binding="wsHttpBinding"
                bindingConfiguration="wsHttp" contract="AmagnoServiceReference.IAmagnoService"
                name="wsHttp">
                <identity>
                    <dns value="test.amagno.org" />
                    <certificate encodedValue="Aw....." />
                </identity>
            </endpoint>
            <endpoint address="http://localhost/AmagnoService/AmagnoService.svc/Basic"
                binding="basicHttpBinding" bindingConfiguration="Basic" contract="AmagnoServiceReference.IAmagnoBasicService"
                name="Basic">
              <identity>
                <dns value="test.amagno.org" />
              </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Da ich bloß ein selbst erstelltes Test Zertifikat verwende, muss vorläufig

<authentication certificateValidationMode="None" revocationMode="NoCheck" />

in der app.config stehen. Das wird sich natürlich später ändern.

Wenn ich den Server auf meinem Windows-7 Rechner laufen lasse, klappt alles wunderbar. Beide Services sind erreichbar. Egal ob ich den Client auf dem selben Rechner oder auf einem anderen laufen lasse.

Wenn ich den Server allerdings auf unserem 1&1 Server (Windows 2008 R2 Server) laufen lasse, klappt nur die Verbindung zum basis Service. Auch wenn der Client ebenfalls auf diesem Server läuft.
Scheinbar wird die Anfrage bereits vom IIS geblockt, denn die Authentifizierungs-Methode des AmagnoUserNamePasswordValidator wird gar nicht erst aufgerufen.

Folgende SecurityNegotiationException bekomme ich, wenn ich eine Methode des gesicherten Service aufrufe:> Fehlermeldung:

Der Aufrufer wurde vom Dienst nicht authentifiziert.
InnerException (FaultException): Die Anforderung für ein Sicherheitstoken konnte nicht erfüllt werden, weil ein Fehler bei der Authentifizierung auftrat.
InnerException StackTrace: bei System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
bei System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)

StackTrace:

Server stack trace:
bei System.ServiceModel.Security.IssuanceTokenProviderBase1.DoNegotiation(TimeSpan timeout) bei System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout) bei System.ServiceModel.Security.TlsnegoTokenProvider.OnOpen(TimeSpan timeout) bei System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) bei System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout) bei System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout) bei System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) bei System.ServiceModel.Channels.SecurityChannelFactory1.ClientSecurityChannel1.OnOpen(TimeSpan timeout) bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) bei System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout) bei System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout) bei System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout) bei System.ServiceModel.Security.SecuritySessionClientSettings1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
bei System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
bei System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei Amagno.WindowsClient.AmagnoServiceReference.IAmagnoService.GetAuthenticatedUser(GetAuthenticatedUserArg arg)
bei Amagno.WindowsClient.AmagnoServiceReference.AmagnoServiceClient.GetAuthenticatedUser(GetAuthenticatedUserArg arg) in d:\Amagno\Client\AmagnoWindowsClient\Service References\AmagnoServiceReference\Reference.cs:Zeile 6849.

Ich habe auf dem Server VisualStudio installiert um debuggen zu können und die Verbindung zum basic Service klappt auch wunderbar...

Leider habe ich keine Ahnung, wo ich ansetzen soll. Ich bin kein Admin und habe auch keinen zu Verfügung.
Wo loggt der IIS die Verbindungsversuche und die Fehler? Wo kann ich da reinschauen? Was muss ich im IIS einstellen, damit die Anfrage durchkommt?

Kann mir jemand weiterhelfen?

Gruß
T-Man

T
T-Man Themenstarter:in
210 Beiträge seit 2006
vor 12 Jahren

Weitere Infos:

Auf dem Win7 Rechner ist die Identität des Anwendungspools "ApplicationPoolIdentity".

Auf dem 2008 Server ist es "NetworkService". Wenn ich es dort mit "ApplicationPoolIdentity" versuche kann ich den Service gar nicht erst starten.

Gruß T-Man

T
T-Man Themenstarter:in
210 Beiträge seit 2006
vor 12 Jahren

Ich habe übrigens mittlerweile die Lösung gefunden.

Ich hatte die Leserechte auf den privaten Schlüssel des Zertifikates für IIS_IUSRS gesetzt. Das war auf dem Win7 Rechner so ok. Auf dem 2008 Server musste ich die Rechte für den "NetworkService" setzen. Logisch, da ja der AppPool mit dieser Identität läuft...