web-dev-qa-db-ja.com

REST APIの認証を設計する

私はRESTサービスを作成および消費するサービスのAPIを作成しています。認証を適切に処理する方法を理解するために、過去数日間を費やしてきました。そして、私はついに何かを思いついたと思います。

これは、アプリケーションスタックに関する次の事実に基づいて考え出しています。

  1. クライアントとサーバーは.NET4にあります(クライアントプロファイルのクライアント部分)
  2. サーバーはWCF RESTを使用して公開します
  3. アプリのユーザー名とパスワードをメモリに保持したくない

3つ目から、トークン認証の形式を使用したかったので、サーバーによって資格情報が検証された後、クライアントはトークンを取得して、アプリの残りの部分全体で使用できるようにします(これにより、次のような他のことができますユーザーのタイムアウト、ユーザーをWebバージョンとデスクトップバージョン間でシームレスに移動できることなど)。呼び出しをリプレイして改ざん防止する方法を理解した後、次のことを思いつきました。

  1. クライアントは認証を試みる前に、ECDiffieHellmanCngクラスを使用してDiffie-Hellman鍵ペアを生成します。
  2. キーペアの公開部分をユーザー名とパスワード(もちろんHTTPS経由)とともにネットワーク経由で送信します。
  3. サーバーはユーザー名とパスワードの組み合わせを認証し、成功した場合は次のことを行います。
    1. 一意のセッショントークンを作成します
    2. 独自のDH鍵ペアを生成し、クライアントから提供された公開鍵から共有秘密を計算します
    3. データベース内のセッショントークン、共有シークレット、ユーザー、および「最後のアクション」時間(ローリング期限切れウィンドウに使用される)を記録します
    4. セッショントークン、その公開DHキー、および認証成功メッセージを返します
  4. クライアントは応答からDHキーを取得し、共有秘密を計算して、トークンと秘密の両方をメモリに格納します。

これ以降、セッショントークンとシークレットの組み合わせは、他のほとんどのREST APIと同様に機能し、リクエストのフィンガープリントとタイムスタンプが付けられ、その後、ある種のHMACが生成されます。クライアントがアクションを実行するときはいつでもサーバーに対して、トークンとシークレットのペアをチェックし、有効で期限切れでない場合はアクションを許可し、セッションの最後のアクションレコードを更新します。

私には明らかな欠陥はなく、おそらくこれに対して過剰設計されていますが、ある時点でこれを行う方法を学ぶ必要があります。 HMACはリプレイ攻撃を防ぎ、DHネゴシエーションはMITM攻撃を防ぐのに役立ちます(HMAC/DHの間の頭上から実行可能な攻撃を考えることはできません)。

誰でもこれを突くことができる穴はありますか?

11
Matt Sieker

独自に開発するのではなく、OpenAM APIを読んで借用することを検討してください。

http://forgerock.com/openam.html

OpenAM Wikiは特に役立ちます

https://wikis.forgerock.org/confluence/display/openam/Home

それらのコンポーネントを使用する必要はありません。しかし、それらのAPIを使用すると、長い目で見ればあなたの人生はよりシンプルになるでしょう。

5
S.Lott

@ S.Lottが100%自分でロールバックしたくないことに同意します。 Windows Azureアクセスコントロールサービス(ACS)を検討することをお勧めします。 ACSはコストがかかりますが、非常に安価(10,000トランザクションで$ 0.01)であり、大量のインフラストラクチャが処理されます。 WIFはクライアントで活用されます。

これは、標準ベース/クレームベースのソリューションでもあります-これは大流行です。これをチェックしてください WCFとRESTとACSの併用 の使用に関する記事。

将来を考えている場合、これはまた、ファイアウォールやパートナーなどの外にモバイルアプリがあるため、成長することができるメカニズムです。ファイアウォールの外側に依存関係を追加するため、使用したくない場合でも、アイデアを確認することをお勧めします。非常に滑らかです。

幸運を! -ビル

2
codingoutloud