2009-10-05 19 views
35

Bien, me falta algo completamente simple aquí, porque he estado buscando en Google durante días, y mirando docenas de respuestas allí, y aquí en SO, y simplemente NO PUEDO hacer que esto funcione , no importa lo que he intentado. El servicio funciona perfectamente bien cuando se llama a través de HTTP simple.WCF sobre SSL - error 404

Aquí está nuestra configuración ... tenemos un dominio, http://www.mydomain.com. Tenemos un certificado SSL instalado en ese dominio de thawte, tal como lo haríamos si estuviéramos asegurando un sitio de comercio electrónico. Todo funciona bien, y puedo ir a http s: //www.mydomain.com y funciona bien. Estoy ejecutando el sitio VS2008, .NET 3.5 en Windows Server 2003 R2.

Ahora, agregué un servicio WCF habilitado para Silverlight a mi sitio, con el que me quiero comunicar mediante SSL. Si yo vaya a http s: //www.mydomain.com/myservice.svc, que me muestra el WSDL-descriptiva "Se ha creado un servicio de" página como se esperaba, lo que demuestra para crear su cliente utilizando

svcutil.exe https:// ... 

EDIT: I realized the url shown for the svcutil in the wsdl file was actually pointing to the physical box name of the web server, not the proper domain. So i went through the steps shown in this blog posting to update the SecureBinding of the website in IIS using the adsutil script. Now the wsdl file shows the correct SSL address, but i still get the same error.

Ahora fui y trataron de conectar mi aplicación Silverlight hasta ella, y no funciona, volviendo una excepción en el resultado de las llamadas asíncronas, afirmando que "el servidor remoto devolvió un error: NotFound. Varios de los blogs que he leído hablaban de limitarlo a problemas de Silverlight al crear una aplicación de Windows de prueba y probar ing para hacer referencia a eso de eso. Bueno, lo hice, e incluso en una aplicación de Windows regulares tratando de acceder al servicio a través de SSL consigo una excepción indicando:

System.ServiceModel.EndpointNotFoundException: 
There was no endpoint listening at https://www.mydomain.com/mysubdir/myservice.svc that could accept the message. 
This is often caused by an incorrect address or SOAP action. 
See InnerException, if present, for more details. ---> 
System.Net.WebException: The remote server returned an error: (404) Not Found. 
at System.Net.HttpWebRequest.GetResponse() 
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) 

Esto a pesar del hecho de que he añadido de forma explícita la referencia de servicio a la aplicación de Windows utilizando el HTTPS esquema y correctamente obtiene todos los métodos y los muestra en Intellisense en el editor.

Tenga en cuenta que este es un servicio que NO requiere el inicio de sesión explícito por parte del usuario. Voy a enviar encabezados personalizados en mis sobres SOAP para verificar que las solicitudes provengan de nuestra aplicación, y solo quiero evitar que los depredadores detecten la línea y seleccionen los encabezados personalizados.

Ahora, al código, donde simplemente debo tener una pequeña configuración estúpida incorrecta, porque por todo lo que he leído, esto debería ser un ejercicio bastante sencillo.

En primer lugar, código subyacente de mi servicio de clase está decorado con los siguientes atributos:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)> 
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> 

La sección ServiceModel de mi web.config en el servidor se ve así:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="basicHttpBinding"> 
       <security mode="Transport"> 
        <transport clientCredentialType ="None"/> 
       </security> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="standingsBehavior"> 
       <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
        <serviceDebug includeExceptionDetailInFaults="false"/> 
       </behavior> 
      </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"> 
     <baseAddressPrefixFilters> 
      <add prefix="http://www.mydomain.com:80"/> 
     </baseAddressPrefixFilters> 
    </serviceHostingEnvironment> 
    <services> 
     <service behaviorConfiguration="standingsBehavior" name="lijslwebdata"> 
      <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/> 
      <!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>--> 
     </service> 
    </services> 
</system.serviceModel> 

Y el La sección ServiceModel de la aplicación.config en mi aplicación de Windows tiene el siguiente aspecto:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="BasicHttpBinding_lijslwebdata" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" 
       sendTimeout="00:01:00" allowCookies="false" 
       bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferSize="65536" maxBufferPoolSize="524288" 
       maxReceivedMessageSize="65536" messageEncoding="Text" 
       textEncoding="utf-8" transferMode="Buffered" 
       useDefaultWebProxy="true"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" 
        maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <security mode="Transport"> 
        <transport clientCredentialType="None" proxyCredentialType="None" realm=""/> 
        <message clientCredentialType="UserName" algorithmSuite="Default" /> 
       </security> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="https://www.mydomain.com/mysubdir/myservice.svc" 
      binding="basicHttpBinding" 
      bindingConfiguration="BasicHttpBinding_lijslwebdata" 
      contract="xdata.lijslwebdata" name="BasicHttpBinding_lijslwebdata" /> 
    </client> 
</system.serviceModel> 
+0

Una pregunta, ¿la baseAddressPrefixFilters necesita establecerse en HTTPS de alguna manera? – eidylon

+0

Realmente estaría interesado en esto también. Tengo un servicio HTTP WCF en este momento y espero problemas al proporcionar la opción de HTTPS. Por favor, recuerde publicar su resultado! :) –

Respuesta

1

Está bien, aparentemente fija el problema, y ​​no tengo ni idea de por qué/cómo.

Esto es lo que hice.

  • que añade un NUEVO VACÍO Silverlight habilitado para servicio WCF
  • entonces he actualizado el web.config para reflejar tanto los servicios
  • Entonces, literalmente, sólo copiar y pegar todo lo relacionado con el primer servicio en el segundo servicio , excepto el nombre.

Por qué esto lo solucionó, no tengo absolutamente ninguna idea.

Fwiw para cualquier persona, aquí está mi nueva sección de web.config ServiceModel con el segundo servicio en ella ...

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="basicHttpBinding"> 
      </binding> 
      <binding name="basicHttpsBinding"> 
       <security mode="Transport"> 
        <transport clientCredentialType ="None"/> 
       </security> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="standingsBehavior"> 
       <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
       <serviceDebug includeExceptionDetailInFaults="false"/> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"> 
     <baseAddressPrefixFilters> 
      <add prefix="http://www.mydomain.com/"/> 
     </baseAddressPrefixFilters> 
    </serviceHostingEnvironment> 
    <services> 
     <service behaviorConfiguration="standingsBehavior" name="lijslwebdata"> 
      <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
     <service behaviorConfiguration="standingsBehavior" name="sslwebdata"> 
      <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="sslwebdata"/> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
</system.serviceModel> 
+3

... y eso me llena del mismo temor que el resto de WCF/Silverlight. Demasiadas variables Crea un nuevo proyecto desde cero y "solo funcionará". ¡No es una opción en el mundo real! (He tenido que hacerlo antes). Gracias por tu respuesta. –

+0

Acepto, ... aunque mi problema no era tanto con Silverlight, porque incluso mi cliente de prueba de Windows no se pudo conectar originalmente. Era algo estrictamente con la parte de WCF sobre SSL. Pero estoy de acuerdo ... No me gustan las cosas que solo se arreglan automágicamente. Es una buena tecnología y todo, solo necesita ser un poco menos frágil. – eidylon

1

Todo parece ser bastante válido, no hay errores evidentes en absoluto ...

Solo una observación/pregunta: ¿dónde está ubicado su archivo * .svc ??

En el mensaje de error, veo:

https://www.mydomain.com/myservice.svc 

Está su archivo * .svc realmente en el directorio virtual de nivel superior de su sitio?

Normalmente, el archivo * .svc está dentro de un directorio virtual en IIS y por lo tanto la dirección sería algo así como:

https://www.mydomain.com/YourVirtualDirectory/myservice.svc 

Por supuesto, puede implementar una aplicación ASP.NET y un servicio WCF * archivo .svc a la raíz de su IIS, pero no es muy común, en mi experiencia.

Sólo una cosita para comprobar .....

Marc

+1

Sí, no, el servicio está realmente en un subdirectorio. Acabo de renombrar los caminos para la seguridad propuesta. Supongo que debería haber puesto un subdirector en el camino falso, pero no, está en un subdirectorio. – eidylon

23

tenía este mismo problema en mi final. Tu publicación me ayudó a descubrir cuál era el problema. aquí está mi sección de modelo de servicio. Descubrí que las claves eran httpsGetEnabled y luego establecía bindingconfiguration Espero que esto ayude.

<system.serviceModel> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="RequestImageBehavior"> 
        <serviceMetadata **httpsGetEnabled**="true" /> 
        <serviceDebug includeExceptionDetailInFaults="false" /> 
        <dataContractSerializer maxItemsInObjectGraph="1073741824" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
     <services> 
      <service behaviorConfiguration="RequestImageBehavior" name="RequestImage"> 
       <endpoint address="" 
          binding="wsHttpBinding" 
          **bindingConfiguration**="HttpsBinding" 
          contract="IRequestImage"> 
       </endpoint> 
       <endpoint address="mex" 
          binding="mexHttpBinding" 
          contract="IMetadataExchange" /> 
      </service> 
     </services> 
     <bindings> 
     **<wsHttpBinding> 
      <binding name="HttpsBinding"> 
      <security mode="Transport"> 
       <transport clientCredentialType="None"/> 
      </security> 
      </binding> 
     </wsHttpBinding>** 
     </bindings> 
    </system.serviceModel> 
+0

Tenía la misma resolución. Descubrí que mi bindingConfiguration no estaba configurada pero mi bindingName era. Una vez que establecí la configuración de enlace las cosas comenzaron a funcionar como deberían. ¡Gracias! –

+0

Configuración de bindingConfiguration resuelto mi problema. ¡Gracias! –

+0

+1 Esto también solucionó mi problema !!!! ¡¡¡Guay!!! – barrypicker

10

Estaba lidiando con esto recientemente, y quiero agregar un tweak. Si sigue las instrucciones anteriores, podrá hacer que el servicio funcione con HTTPS, pero no simultáneamente en HTTP y HTTPS. Para ello, es necesario tener dos nodos de configuración de punto final, uno para cada protocolo de la siguiente manera:

<service name="MyCompany.MyService" > 
    <endpoint address="" behaviorConfiguration="AspNetAjaxBehavior" 
     binding="webHttpBinding" contract="MyCompany.MyService" bindingConfiguration="sslBinding" /> 
    <endpoint address="" behaviorConfiguration="AspNetAjaxBehavior" 
     binding="webHttpBinding" contract="MyCompany.MyService" /> 
    </service> 

(Tomado de mi base de código, ajuste behaviorConfiguration y vinculante según el caso)

+0

¡Gracias! De hecho, descubrí que mi servicio SSL a través de HTTPS arrojaba un 404 sin el punto final HTTP. Agregar el punto final HTTP lo solucionó. Ridículo. – Rocklan

0

No funcionó para antes porque ha llamado a su configuración básica de HTTP "basicHttpBinding" pero no ha hecho referencia a esa configuración en su etiqueta con bindingConfiguration = "basicHttpBinding"

En los cambios que sí funcionaron al agregar otra configuración de servicio, hizo referencia a la configuración de enlace que contiene el nodo por lo tanto causando trabajo.

2

Tuve el mismo problema y pasé un día para resolver este problema. Finalmente debajo de la configuración me funcionó para el acceso HTTPS.

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="basicHttpBinding"> 
      </binding> 
      <binding name="basicHttpsBinding"> 
       <security mode="Transport"> 
        <transport clientCredentialType ="None"/> 
       </security> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="standingsBehavior"> 
       <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
       <serviceDebug includeExceptionDetailInFaults="false"/> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"> 
     <baseAddressPrefixFilters> 
      <add prefix="http://www.mydomain.com/"/> 
     </baseAddressPrefixFilters> 
    </serviceHostingEnvironment> 
    <services> 
     <service behaviorConfiguration="standingsBehavior" name="lijslwebdata"> 
      <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
     <service behaviorConfiguration="standingsBehavior" name="sslwebdata"> 
      <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="sslwebdata"/> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
</system.serviceModel> 
7

Me acabo de pasar unas horas en esto y resultó que mi problema era el nombre del servicio

<services> 
     <service name="TimberMill.Web.Data.LogReceiverService"> 
     <endpoint binding="basicHttpBinding" bindingConfiguration="basicBinding" 
        contract="NLog.LogReceiverService.ILogReceiverServer" /> 
     </service> 
    </services> 

tenían que coincidir exactamente con la entrada similar en mi archivo * .svc.

<%@ ServiceHost 
    Language="C#" 
    Debug="true" 
    Service="TimberMill.Web.Data.LogReceiverService, TimberMill.Web" 
    Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" 
    CodeBehind="LogReceiverService.svc.cs" 
%> 

No estoy seguro si estaba relacionado con mi uso de Autofac. Todo funcionaba bien en HTTP simple. Sin embargo, falló en HTTPS.

Bueno, creo que sí, no quiero molestar nada ahora probando con más detalle para no enojar a los dioses WCF-Config y mi configuración se rompe de nuevo. YMMV.

+1

Sí serviceName solucionó esto por mí – saille

0

Otra cosa para comprobar si se encuentra con el mismo error 404 que OP. Jugué un montón de cosas, pero finalmente la solución se redujo a simplemente agregar el espacio de nombres a mi servicio web.config.

Así que el viejo y simple ServiceFoo y IServiceFoo no funcionó:

<services> 
    <service behaviorConfiguration="quuxBehavior" name="ServiceFoo"> 
     <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="IServiceFoo"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
    </service> 
    </services> 

embargo, la adición del espacio de nombres (ProjectBar) funcionó:

<services> 
    <service behaviorConfiguration="quuxBehavior" name="ProjectBar.ServiceFoo"> 
     <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="ProjectBar.IServiceFoo"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
    </service> 
    </services> 
3

En mi caso ninguna de estas respuestas ayudado.

En cambio, necesitaba add a duplicate <binding> section that has no name attribute set.

Aquí es el volcado de la sección correspondiente del archivo web.config de mi servicio:

<behaviors> 
    <serviceBehaviors> 
     <behavior name="ServiceBehaviour"> 
      <serviceMetadata 
       httpsGetEnabled="true" 
       httpsGetUrl="RemoteSyncService.svc" 
       httpGetBindingConfiguration="bindingConfig" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     <behavior name=""> 
      <serviceMetadata 
       httpsGetEnabled="true" 
       httpsGetUrl="RemoteSyncService.svc" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
    </serviceBehaviors> 
</behaviors> 

<bindings> 
    <basicHttpBinding> 
    <binding name="bindingConfig" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed"> 
     <security mode="Transport"> 
      <transport clientCredentialType="None"/> 
     </security> 
     <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/> 
    </binding> 

    <!-- Add binding with EMPTY/MISSING name, see https://forums.iis.net/t/1178173.aspx --> 
    <binding maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed"> 
     <security mode="Transport"> 
      <transport clientCredentialType="None"/> 
     </security> 
     <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/> 
    </binding> 
    </basicHttpBinding> 
</bindings> 

Yo espero que esto podría ser útil para alguien, algún día.

+1

Solo para validar esta publicación, esta fue la única sugerencia que funcionó para mí –