2009-05-08 4 views
1

Ich habe eine Service Provider-Implementierung für OAuth geschrieben, und einer der Devs hat einen Fehler bei der Implementierung der Abfrageparameter gefunden. Ich vermisste völlig die lexicographical ordering Anforderung in der OAuth-Spezifikation und wurde nur eine einfache Zeichenfolge Art auf den Namen WertparameterOAuth - lexikographischer Byte-Wert in C#

Angesichts der folgenden URI-Anforderung von dem Verbraucher zu tun:

http://api.com/v1/People/Search?searchfor=fl&[email protected]&Include=addresses 

Die resultierende Signaturbasis sollte die Reihenfolge Parameter wie:

http://api.com/v1/People/Search?searchfor=fl&[email protected]&include=addresses 
:

Include=addresses, [email protected], searchfor=fl 

die folgende URI-Anforderung von dem Verbraucher Gegeben

sollte die sich ergebende Signatur, die Parameter als Basis bestellen:

[email protected], include=addresses, searchfor=fl 

Beachten Die Differenz in der Abfragezeichenparameter „enthalten“. Von dem, was ich verstehe, wird lexikographische Byte-Wert-Reihenfolge Parameter mit dem Ascii-Wert bestellen und dann Bestellung asc.

Da I = 73 und i = 105, sollte das Kapital I vor dem Kleinbuchstaben i bestellt werden.

Ich habe folgendes bisher:

IEnumerable<QueryParameter> queryParameters = parameters 
.OrderBy(parm => parm.Key) 
.ThenBy(parm => parm.Value) 
.Select(
parm => new QueryParameter(parm.Key, UrlEncode(parm.Value))); 

Aber das wird das ASCII-Zeichen für Zeichen Art nicht decken (INCLUDE = Test & Include = Test nicht richtig sortieren).

Irgendwelche Gedanken darüber, wie man einen effizienten Algorithmus entwickelt, der dieses Problem löst? Oder wie man die Sortierung über ICompare sensitiv macht?

Antwort

0

ich das Problem, indem Sie einen benutzerdefinierten Vergleich zu schaffen, jedoch gelöst, so scheint es klobig und ich fühle es ein besserer Weg sein muss:

public class QueryParameterComparer : IComparer<QueryParameter> { 
    public int Compare(QueryParameter x, QueryParameter y) { 
      if(x.Key == y.Key) { 
      return string.Compare(x.Value, y.Value, StringComparison.Ordinal); 
      } 
      else { 
      return string.Compare(x.Key, y.Key, StringComparison.Ordinal); 
      } 
    } 
} 

Mit dem Ordinal String-Vergleich ist das, was für mich habe es geschaffen. Es macht Byte-Vergleiche, was genau ich brauchte.

0

Nick, wie Sie StringComparison.Ordinal entdeckt haben, ist der Weg zu gehen. Ich wollte nur eine Warnung ausrufen, die Sie sortieren, nachdem Sie URI jeden der Schlüssel und Werte kodieren.

BTW, es gibt schon ein paar OAuth-Bibliotheken da draußen, DotNetOpenAuth ist mein Favorit (Disclaimer: aus voreingenommenen Gründen). Bist du sicher, dass du diesen bauen/pflegen willst?

+0

Andrew: Thx für die Antwort. Ich habe meine eigene Implementierung von Service Provider aus 2 Gründen gerollt: 1.Ich wollte das OAuth-Protokoll für mich selbst und für unsere Kunden verstehen - welchen besseren Weg, um Verständnis zu erlangen, als indem wir es tun 2. Es gibt Geschäftsfälle, die eine Erweiterung des Protokolls erforderten - https://demo.staging.fellowshiponeapi.com/v1/ Util/AuthDocs.help Ich habe DotNetOpenAuth betrachtet, es scheint wie eine sehr glatte Implementierung - Sie müssen es kaputt gemacht haben, um so viel Funktionalität in dort zu bekommen, wie Sie taten! – Nick

0

Ich hatte Probleme mit dem gleichen Ausdruck (auch wenn es nicht mehr in der OAuth-Dokumentation falsch geschrieben ist, -. Wenn dies der Ort ist, wo es falsch geschrieben wurde)

Wikipedia sais „lexicographical ordering“ Bedeutung hat, wenn der Brief Bestellung ist gegeben. Sie gibt die Reihenfolge der Elemente (Buchstaben) an, wenn die Reihenfolge des Elements bereits festgelegt ist.

Es klingt vernünftig für mich. :).