サードパーティの開発者がアプリケーションのデータにアクセスするために使用する ASP.NET Web API を使用してRESTful Web サービスを構築したいと考えています。
私はOAuthについてかなり読んできましたが、それが標準のようです。しかし、それがどのように機能するか (そして実際に機能するか!) を説明するドキュメント付きの優れたサンプルを見つけるのは、非常に難しいようです (特に OAuth の初心者にとっては)。
実際にビルドして動作し、これを実装する方法を示すサンプルはありますか?
多数のサンプルをダウンロードしました:
- DotNetOAuth - 初心者の観点から見るとドキュメントは絶望的
- Thinktecture - 構築できない
私はまた、単純なトークンベースのスキームを提案するブログを見ました(例えばこれ) - これは車輪の再発明のように思えますが、概念的にはかなり単純であるという利点があります。
SO にはこのような質問がたくさんあるようですが、良い回答はありません。
みんなこの空間で何をしているのでしょうか?
ベストアンサー1
アップデート:
このリンクを他の回答に追加しましたASP.NET Web API で JWT 認証を使用する方法JWT に興味のある方はこちらをご覧ください。
HMAC 認証を Web API のセキュリティ保護に適用し、問題なく動作しました。HMAC 認証では、メッセージを HMAC ハッシュするために、コンシューマーとサーバーの両方が知っている各コンシューマーの秘密キーを使用します。HMAC256 を使用する必要があります。ほとんどの場合、コンシューマーのハッシュされたパスワードが秘密キーとして使用されます。
メッセージは通常、HTTP リクエスト内のデータ、または HTTP ヘッダーに追加されたカスタマイズされたデータから構築され、メッセージには次のものが含まれる場合があります。
- タイムスタンプ: リクエストが送信された時刻 (UTC または GMT)
- HTTP 動詞: GET、POST、PUT、DELETE。
- 投稿データとクエリ文字列、
- メールアドレス
内部的には、HMAC 認証は次のようになります。
コンシューマーは、署名 (hmac ハッシュの出力) を構築した後、HTTP リクエストのテンプレートを Web サーバーに送信します。
User-Agent: {agent}
Host: {host}
Timestamp: {timestamp}
Authentication: {username}:{signature}
GET リクエストの例:
GET /webapi.hmac/api/values
User-Agent: Fiddler
Host: localhost
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
署名を取得するためにハッシュするメッセージ:
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
クエリ文字列を含む POST リクエストの例 (以下の署名は正しくありません。単なる例です)
POST /webapi.hmac/api/values?key2=value2
User-Agent: Fiddler
Host: localhost
Content-Type: application/x-www-form-urlencoded
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
key1=value1&key3=value3
署名を得るためにハッシュするメッセージ
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
key1=value1&key2=value2&key3=value3
フォーム データとクエリ文字列は順序どおりである必要があることに注意してください。そうすることで、サーバー上のコードはクエリ文字列とフォーム データを取得して正しいメッセージを構築します。
HTTP リクエストがサーバーに届くと、認証アクション フィルターが実装され、リクエストを解析して HTTP 動詞、タイムスタンプ、URI、フォーム データ、クエリ文字列などの情報を取得し、それらに基づいてサーバー上の秘密キー (ハッシュされたパスワード) を使用して署名 (hmac ハッシュを使用) を構築します。
秘密キーは、リクエストのユーザー名を使用してデータベースから取得されます。
次に、サーバー コードは、リクエストの署名と構築された署名を比較します。等しい場合は認証に合格し、等しくない場合は失敗します。
署名を作成するコード:
private static string ComputeHash(string hashedPassword, string message)
{
var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
string hashString;
using (var hmac = new HMACSHA256(key))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
では、リプレイ攻撃を防ぐにはどうすればよいでしょうか?
タイムスタンプに次のような制約を追加します。
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(servertime: リクエストがサーバーに到着した時刻)
また、リクエストの署名をメモリにキャッシュします (MemoryCache を使用し、一定時間内に保持する必要があります)。次のリクエストが前のリクエストと同じ署名で送信された場合、そのリクエストは拒否されます。
デモコードは次のようになります:https://github.com/cuongle/Hmac.WebApi