2013-06-07 4 views
6

Sto utilizzando un meccanismo di autenticazione personalizzato mediante l'invio di un token di sessione. La presenza del token è controllata in DelegatingHandler che imposta il principio corrente in modo concordato. Se il principale non è autorizzato a chiamare il metodo ApiController, il controller invia uno stato non autorizzato 401. Dato che RFC 2616 richiede sempre l'impostazione dell'autenticazione WWW-Authenticate sempre quando si invia una risposta 401, il mio DelegatingHandler si occupa di questo.L'impostazione dell'intestazione di risposta dell'autenticazione WWW all'interno di DelegatingHandler causa il caos su w2k3

Ora in uno scenario con Web API self-hosted una richiesta che dovrebbe rispondere con 401 funziona correttamente su Windows 7, ma su Windows Server 2003 muore con l'eccezione "Una connessione esistente è stata forzatamente chiusa dall'host remoto" . Inoltre ho notato che un punto di interruzione nel metodo controller viene colpito due volte su W2k3 in contrasto con una volta in Win7, come se HttpClient in qualche modo ritentasse la richiesta dopo aver ricevuto la risposta 401.

Quando disconnetto la riga con l'intestazione WWW-Authenticate, il programma funziona correttamente. Si prega di consultare i seguenti esempi di codice per un esempio di riproduzione minimalista all'interno di un'applicazione console.

TestController.cs:

public class TestController : ApiController 
{ 
    public HttpResponseMessage Get() 
    { 
     return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "go away"); 
    } 
} 

AuthenticationHandler.cs:

public class AuthenticationHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(task => 
     { 
      HttpResponseMessage response = task.Result; 
      if (response.StatusCode == HttpStatusCode.Unauthorized && 
       !response.Headers.Contains("WWW-Authenticate")) 
      { 
       // comment out this line and the code works 
       response.Headers.Add("WWW-Authenticate", "SessionToken"); 
      } 
      return response; 
     }); 
    } 
} 

Program.cs:

static void Main(string[] args) 
    { 
     HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://localhost:81"); 
     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}" 
     ); 
     config.MessageHandlers.Add(new AuthenticationHandler()); 

     using (HttpSelfHostServer server = new HttpSelfHostServer(config)) 
     using (HttpClient client = new HttpClient()) 
     { 
      server.OpenAsync().Wait(); 

      try 
      { 
       HttpResponseMessage response = client.GetAsync("http://localhost:81/api/test").Result; 
       Console.Out.WriteLine(response.StatusCode); 
      } 
      catch (AggregateException ex) 
      { 
       Console.Out.WriteLine(ex.ToString()); 
      } 

      server.CloseAsync().Wait(); 
     } 

     Console.In.ReadLine(); 
    } 

Sto chiamando correttamente l'API? Qualche idea su cosa possa essere sbagliato?

risposta

3

È necessario installare .net Framework 4.0.3. Le versioni precedenti di .net framework non potevano impostare l'intestazione www-authenticate. Prendilo here, maggiori informazioni sul problema sono in KB2600211.

Problemi correlati