2

私は OAuth のサービス プロバイダーの実装を作成しましたが、開発者の 1 人が、実装がクエリ パラメーターを並べ替える方法にバグを発見しました。OAuth 仕様の辞書式順序要件を完全に見逃しており、名前値パラメーターで基本的な文字列の並べ替えを行っていました。

コンシューマーからの次の URI 要求があるとします。

http://api.com/v1/People/Search?searchfor=fl&communication=test@test.com&Include=addresses

結果の署名ベースは、パラメーターを次のように順序付けする必要があります。

Include=addresses, communication=test@test.com, searchfor=fl

コンシューマーからの次の URI 要求があるとします。

http://api.com/v1/People/Search?searchfor=fl&communication=test@test.com&include=addresses

結果の署名ベースは、パラメーターを次のように順序付けする必要があります。

communication=test@test.com, include=addresses, searchfor=fl

クエリ文字列パラメーター「include」の大文字と小文字の違いに注意してください。私が理解していることから、辞書式のバイト値の順序付けは、ascii 値を使用してパラメーターを順序付けてから、asc を順序付けます。

I = 73 および i = 105 であるため、大文字の I は小文字の i の前に並べる必要があります。

これまでのところ、次のものがあります。

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

しかし、それは文字ソートによるASCII文字をカバーしません(IncLude=test&Include=testは正しくソートされません)。

この問題に答える効率的なアルゴリズムを作成する方法について何か考えはありますか? または、ICompare を使用してソートの大文字と小文字を区別する方法は?

4

3 に答える 3

0

カスタム比較ツールを作成して問題を解決しましたが、不格好なようで、もっと良い方法があるはずだと思います。

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);
          }
    }
} 

序数の文字列比較を使用することは、私にとってそれをしたことです。それはまさに私が必要としていたバイト比較を行います。

于 2009-05-08T12:34:10.140 に答える
0

ニック、あなたがStringComparison.Ordinalを発見したように、行く方法です。各キーと値をURIエンコードした後にソートすることに注意してください。

ところで、すでにいくつかのOAuthライブラリがあり、DotNetOpenAuthが私のお気に入りです(免責事項:偏った理由で)。これを作成/保守してもよろしいですか?

于 2009-05-08T18:57:05.490 に答える
0

同じ式に問題がありました (ただし、OAuth のドキュメントではスペルが間違っていませんが、それがスペルミスの場所である場合)。

ウィキペディアによると、文字の順序が与えられている場合、「辞書式順序付け」には意味があります。要素の順序が既に指定されている場合、一連の要素 (文字) の順序を指定します。

私には合理的に聞こえます。:)。

于 2009-10-08T19:33:28.497 に答える