2012-03-30 8 views
5

Ho un problema con un servizio WCF che utilizza l'autenticazione di Windows su uno dei server in cui lo sto distribuendo (è una macchina Windows Server 2008 R2), mentre funziona in modo impeccabile su tutte le altre macchine a cui ho accesso (Windows 7, Windows Server 2008 e Windows Server 2008 R2). Sono riuscito a riprodurre il problema con un'applicazione di esempio veramente semplice che esclude più o meno completamente il mio codice come causa del problema.Impossibile eseguire l'URL quando si chiama un servizio WCF con l'autenticazione di Windows

La domanda minima posso riprodurre il problema con una piccola modifica del modello di progetto servizio 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); 
    } 
} 

Fondamentalmente abilitato compatibilità ASP.NET (ho bisogno perché il codice effettivo utilizza un HttpHandler per autenticazione) e viene restituito il nome utente dell'utente autenticato.

I contenuti di web.config sono i seguenti:

<?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> 

dati i due punti finali: una con l'indirizzo predefinito, l'altro con un indirizzo relativo. Chiamando il primo esito positivo anche sul server problematico, mentre la chiamata alla seconda non riesce con errore seguente:

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 chiamata non riesce solo se si utilizza la pipeline classico (ne ho bisogno a causa della HttpHandler, ma il problema può essere riprodotto anche senza di esso). Con la pipeline integrata il problema è finito. Anche se disattivare l'autenticazione di Windows, il problema è andato così:

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

Ho notato un altro dettaglio con una HttpHandler registrati. Il valore della proprietà HttpRequest.CurrentExecutionFilePath per l'endpoint con l'indirizzo relativo è diverso tra il server problematico (~/Service1.svc/problem) ei server di lavoro (~/Service1.svc). Anche se non ho molta familiarità con IIS, sospetto che questo possa suggerire la causa del problema, forse qualcosa legato al routing delle richieste?

Sono a corto di idee quindi sto postando questo qui nella speranza che qualcuno riconoscerà quale potrebbe essere il problema. Qualsiasi suggerimento è benvenuto.

+1

Hai la riscrittura dell'URL su IIS attivata? Questo odora di un problema di autorizzazione di qualche tipo. [Qual è la differenza tra la modalità pipeline classica e integrata in IIS7?] (Http://stackoverflow.com/questions/3062709/what-is-the-difference-between-classic-and-integrated-pipeline-mode-in- 7) Potrebbe essere utile. –

+0

@PetarVucetin Ho controllato e la riscrittura dell'URL non è abilitata sul server.Anche se il tuo commento non ha risposto esattamente alla mia domanda, il link che mi hai fornito mi ha dato alcune idee: sono riuscito a riconfigurare la mia applicazione per farlo funzionare con la modalità pipeline integrata dove il problema non si manifesta. Mi piacerebbe ancora sapere come farlo funzionare in modalità pipeline classica, ma se non ottengo una risposta migliore chiarendo che per me, il tuo commento è il miglior candidato per la taglia. Mi ha fatto risolvere il problema immediato, dopotutto. –

+0

Grazie Damir. Quando avrò un po 'di tempo, posso provare a riprodurre il problema. Mi fa il solletico al mio osso di debug ... –

risposta

0

Il problema potrebbe essere l'indirizzo "~/Service1.svc/problema"

Quando l'indirizzo è "~/Service1.svc" la chiamata colpisce il file SVC, e utilizza le informazioni nel file per trovare l'interfaccia e quindi la configurazione per quell'interfaccia.

Quando si utilizza un indirizzo relativo senza un file svc, viene visualizzato l'indirizzo nel file di configurazione.

Avete una directory "Service1.svc" su uno dei server, oppure l'indirizzo è senza ".svc" sul server in cui funziona?

+0

Né. Durante la risoluzione dei problemi a scopo di test, ho creato una nuova applicazione su tutti i server con solo i file del progetto di test sopra indicato: 'Service1.svc',' Web.config', 'bin \ TestService.dll'. –

1

Hai la riscrittura dell'URL su IIS attivata? Questo odora di un problema di autorizzazione di qualche tipo. What is the difference between Classic and Integrated pipeline mode in IIS7? Potrebbe essere utile.

+0

Grazie per il link. Mi ha fatto leggere le differenze e alla fine sono riuscito a far funzionare la mia app in modalità pipeline integrata. Sono comunque curioso di sapere perché non funziona in modalità pipeline classica su quel server, però. –

Problemi correlati