2016-03-29 7 views
0

Ich befolge den HMAC-Authentifizierungsansatz wie beschrieben here in einer Web-Api-Anwendung, die auf Azure bereitgestellt wird, aber ich habe 404 Fehler mehr als die Hälfte der Zeit auf dem gleichen HTTP GET Anrufe.Web API HMAC Authentication- Intermittent 404 nicht gefunden Antwort

Es scheint, dass, wenn ich den Aufruf an den Server, auch wenn meine Anfrage URI des Formats ist,

http://mywebapp.azurewebsites.net/api/foo/bar?val=123 

Etwa die Hälfte der Zeit, die Anforderungs-URI in der HttpResponseMessage kommt zurück als

http://mywebapp.azurewebsites.net/Account/Login?ReturnUrl=%2Fapi%2Ffoo%2Fbar%3Fval%3D123 

Dies geschieht nur, wenn ich das HMACAuthentication-Attribut auf meinem Foo-Controller anwenden.

Der komische Teil ist, dass es nicht jedes Mal passiert und nicht passiert, wenn ich auf localhost laufe. Ich habe das Beispiel genau aus dem Github Repo kopiert. Ich dachte, die Serverzeit könnte etwas damit zu tun haben, aber das erklärt nicht, warum die Anfragen manchmal durchgehen und bei anderen fehlschlagen ... es sollte konsistent sein. Nicht sicher, welcher Teil des Codes relevant ist, um hier niedergelegt zu werden, also lassen Sie mich bitte wissen, was helfen würde, um zu sehen.

Ich würde jede Einsicht darüber schätzen. Danke im Voraus!

Antwort

1

Es stellte sich heraus, das Problem trat in der isReplayRequest Methode im Repo auf.

Hier ist die ursprüngliche Methode Definition:

private bool isReplayRequest(string nonce, string requestTimeStamp) 
    { 
     if (System.Runtime.Caching.MemoryCache.Default.Contains(nonce)) 
     { 
      return true; 
     } 

     DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc); 
     TimeSpan currentTs = DateTime.UtcNow - epochStart; 

     var serverTotalSeconds = Convert.ToUInt64(currentTs.TotalSeconds); 
     var requestTotalSeconds = Convert.ToUInt64(requestTimeStamp); 

     if ((serverTotalSeconds - requestTotalSeconds) > requestMaxAgeInSeconds) 
     { 
      return true; 
     } 

     System.Runtime.Caching.MemoryCache.Default.Add(nonce, requestTimeStamp, DateTimeOffset.UtcNow.AddSeconds(requestMaxAgeInSeconds)); 

     return false; 
    } 

Das Problem bei den zweiten auftritt, wenn die Bedingung, wo der serverTotalSeconds und requestTotalSeconds sind ganze Zahlen ohne Vorzeichen.

Es wurden periodische Fälle, in denen die Zeitstempel negativen enden würden (dh die requestTotalSeconds war größer als serverTotalSeconds von 1), der den Wert von (serverTotalSeconds - requestTotalSeconds) einstellen würde, am Ende als 18446744073709551615, die der Maximalwert UInt64 ist kann halten.

In meinem Fall habe ich zwei TimeSpan-Objekte verwendet, um die Zeit zu vergleichen und den Unterschied in Sekunden abzuleiten.

Hoffe das hilft jemand anderem.