2012-03-30 27 views
5

Tengo un problema con un servicio WCF que usa autenticación de Windows en uno de los servidores en los que lo estoy implementando (es una máquina Windows Server 2008 R2), mientras funciona sin problemas en todas las otras máquinas a las que tengo acceso (Windows 7, Windows Server 2008 y Windows Server 2008 R2). Logré reproducir el problema con una aplicación de muestra realmente simple que excluye más o menos por completo mi código como la causa del problema.Error al ejecutar la URL al llamar a un servicio WCF con autenticación de Windows

La aplicación mínima que puedo reproducir el problema con una pequeña modificación de la plantilla de proyecto de servicio WCF:

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    string GetData(int value); 
} 

[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)] 
public class Service1 : IService1 
{ 
    public string GetData(int value) 
    { 
     return string.Format("You entered: {0}\nUsername: {1}", 
      value, 
      ServiceSecurityContext.Current == null ? 
       "<null>" : 
       ServiceSecurityContext.Current.PrimaryIdentity.Name); 
    } 
} 

Básicamente me permitió la compatibilidad de ASP.NET (lo necesito porque el código real utiliza un HttpHandler de autenticación) y se devuelve el nombre de usuario del usuario autenticado.

El contenido de web.config son los siguientes:

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    <authentication mode="Windows"/> 
    </system.web> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="ServiceBehavior"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="HttpWindowsBinding" maxReceivedMessageSize="2147483647"> 
      <readerQuotas maxBytesPerRead="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647"/> 
      <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Windows" /> 
      </security> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" /> 
    <services> 
     <service name="TestService.Service1" behaviorConfiguration="ServiceBehavior"> 
     <endpoint address="" 
        binding="basicHttpBinding" 
        bindingConfiguration="HttpWindowsBinding" 
        contract="TestService.IService1" /> 
     <endpoint address="problem" 
        binding="basicHttpBinding" 
        bindingConfiguration="HttpWindowsBinding" 
        contract="TestService.IService1" /> 
     </service> 
    </services> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 
</configuration> 

Aviso los dos puntos finales: uno con la dirección por defecto, el otro con una dirección relativa. Llamando el primero tiene éxito, incluso en el servidor problemático, mientras que la llamada a la segunda falla con el error siguiente:

Exception type: HttpException 
Exception message: Failed to Execute URL. 
at System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.BeginExecuteUrl(String url, String method, String childHeaders, Boolean sendHeaders, Boolean addUserIndo, IntPtr token, String name, String authType, Byte[] entity, AsyncCallback cb, Object state) 
at System.Web.HttpResponse.BeginExecuteUrlForEntireResponse(String pathOverride, NameValueCollection requestHeaders, AsyncCallback cb, Object state) 
at System.Web.DefaultHttpHandler.BeginProcessRequest(HttpContext context, AsyncCallback callback, Object state) 
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

La llamada sólo falla cuando se utiliza la tubería clásica (I lo necesitan debido a la HttpHandler, pero el problema se puede reproducir incluso sin él). Con la tubería integrada, el problema se ha ido. Además, si desactivo la autenticación de Windows, el problema se ha ido así:

<binding name="HttpBinding" maxReceivedMessageSize="2147483647"> 
    <readerQuotas maxBytesPerRead="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647"/> 
    <security mode="None"> 
    <transport clientCredentialType="None" /> 
    </security> 
</binding> 

me he dado cuenta otro detalle con un HttpHandler registrado. El valor de la propiedad HttpRequest.CurrentExecutionFilePath para el punto final con la dirección relativa difiere entre el servidor problemático (~/Service1.svc/problem) y los servidores que trabajan (~/Service1.svc). Aunque no estoy tan familiarizado con IIS, sospecho que esto podría indicar la causa del problema, tal vez algo relacionado con el enrutamiento de las solicitudes.

Me estoy quedando sin ideas, por lo tanto, estoy publicando aquí con la esperanza de que alguien sepa cuál es el problema. Cualquier sugerencia es bienvenida.

+1

¿Tiene la reescritura de URL en IIS activada? Esto huele a un problema de permiso de algún tipo. [¿Cuál es la diferencia entre el modo de canalización clásica e integrada en IIS7?] (Http://stackoverflow.com/questions/3062709/what-is-the-difference-between-classic-and-integrated-pipeline-mode-in- iis7) Podría ser útil. –

+0

@PetarVucetin Revisé y la reescritura de URL no está habilitada en el servidor.Si bien su comentario no respondió exactamente a mi pregunta, el enlace que proporcionó me dio algunas ideas: logré reconfigurar mi aplicación para que funcione con el modo de canalización integrado donde el problema no se manifiesta. Todavía me gustaría saber cómo hacerlo funcionar en el modo de canal clásico, pero si no obtengo una mejor respuesta aclarando eso para mí, tu comentario es el mejor candidato para la recompensa. Sí me ayudó a resolver el problema inmediato, después de todo. –

+0

Gracias Damir. Cuando tenga algo de tiempo, puedo intentar reproducir el problema. Simplemente hace cosquillas a mi hueso de depuración ... –

Respuesta

0

El problema puede ser la dirección "~/Service1.svc/problema"

Cuando la dirección es "~/Service1.svc" la llamada golpea el archivo SVC, y utiliza la información en el archivo para encontrar la interfaz y luego la configuración para esa interfaz.

Cuando utiliza una dirección relativa sin un archivo svc, mira la dirección en el archivo de configuración.

¿Tiene un directorio "Service1.svc" en uno de los servidores, o es la dirección sin el ".svc" en el servidor donde funciona?

+0

Ninguno. Durante la resolución de problemas para fines de prueba, he creado una nueva aplicación en todos los servidores con solo los archivos del proyecto de prueba mencionado anteriormente: 'Service1.svc',' Web.config', 'bin \ TestService.dll'. –

1

¿Tiene la reescritura de URL en IIS activada? Esto huele a un problema de permiso de algún tipo. What is the difference between Classic and Integrated pipeline mode in IIS7? Podría ser útil.

+0

Gracias por el enlace. Me hizo leer sobre las diferencias y, al final, logré que mi aplicación funcionara en modo de canalización integrada. Todavía tengo curiosidad de por qué no funciona en el modo de canal clásico en ese servidor, sin embargo. –

Cuestiones relacionadas