5

私はいくつかの開発のために一連のRESTfulサービスを実装しており、そのうちの1つは認証サービスです。

この認証サービスは、次の2種類のIDを認証します。

  • アプリケーションAppKeyベースの認証。これにより、クライアントは残りのサービスにアクセスするためにキーを登録する必要があります
  • ユーザーよく知られている資格情報(ユーザー+パスワード)ベースのユーザー認証。これにより、人間とマシンはクライアントアプリケーションを介してこれらのRESTfulサービスを操作できます。

これらのRESTfulサービスステートレスです。

クライアントアプリケーションが認証サービスに対して認証する場合、または人間またはマシンが資格情報を使用してIDとして認証する場合、両方の操作でそれぞれAppTokenUserTokenが生成されます。

これらのトークンはソルトハッシュであるため、RESTfulインフラストラクチャへの後続のリクエストは、AppKeyクレデンシャルを共有せずに認証されます。

完全にステートレスなアプローチの観点から、これらのトークンはサービスレイヤーのどこにも保存するのではなく、ある種のクライアント側の状態で保存する必要があります(fe、WebクライアントはHTTP Cookieを使用して保存します)。これが私の現在の実装が現在どのように機能しているかです。

これらのトークンを使用して各リクエストを再認証し、サービスレイヤーがクライアントからのトークンを受信できるようにするため、クライアントからのトークンを比較し、それが有効なトークンであるかどうかを確認して、サービスレイヤーでトークンを再生成し、クライアントが所有するものは高すぎるため、トークンかどうかを確認するために、有効期限と所有者(トークンが作成されたアプリケーションまたはユーザー)の両方を持つサービスレイヤーAppTokenUserTokenを実装しましたクライアントからの送信はトークンストアに存在します。

クライアントはどのようにインタラクティブに認証を解除しますか? クライアント側のセキュリティ状態を削除するだけです。Webクライアントの場合、認証Cookieを削除し、ページを更新するだけで、クライアントは認証Cookieを検出せず、ユーザーはログインページにリダイレクトされます。

RESTfulサービスの観点からは、これはステートレスな認証解除です。クライアントは、サービス層の疑似認証状態を持つトリックを認識していません。これは、サービス実装の詳細(パフォーマンスの最適化)にすぎません。

ステートレスサービスの長所をリストするつもりはありません。これは、このアプローチが進むべき道であると確信しているためですが、問題が見つかりました。ステートレス認証/非認証は、クライアントがセッションを閉じることをサーバーに通知しないことを意味します。 、したがって、セキュリティストアは多くの役に立たないレコードで終わります

サービスクライアントが限られた時間(fe、1時間、3時間、1日...)のクライアントである場合、これは大きな問題ではありませんが、ユーザーが永久に認証される必要がある場合(8か月、1年)はどうなりますか期限切れのトークンとはどのように区別しますか?

この状況を解決するためのいくつかのアプローチがあります。

  1. サービスレイヤーはリクエストを受信するたびにトークンの有効期限を更新するため、自動化されたプロセスにより、トークンの任意の有効期限(fe 24時間)を定義して有効期限が切れたトークンが削除される場合があります

  2. アーキテクチャのステートレスな性質を損ない、クライアントが認証されたくないことをサービスレイヤーに通知できるようにすることで、サービスは関連付けられたトークンをクライアントセッションにドロップできますただし、クライアントがWebクライアントを閉じるとどうなりますか?ユーザートークンを削除する必要があることをサービスに積極的に通知することはありません...したがって...ゾンビトークンはまだ存在するため、自動化されたプロセスで削除する必要がありますが...ゾンビトークンとは何ですか?このアプローチは好きではありません

  3. 完全にステートレスな認証、ストアなし、リクエストごとの認証。

これが質問です!1.、2。、または3.でなくても、提案されているアプローチは何ですか。その理由は何ですか。

この長い読書に感謝します-私は正直に言って、質問の結論は誰にとっても非常に役立つだろうと信じています-!

4

2 に答える 2

7

数3

ステートレス認証、トークンベース。トランスポートレベルの暗号化を想定しています。

  • [X]SS--XはSの公開鍵によって署名されています
  • [X|Y]-同じエンベロープ内のXとY
  • Y [M]SY -> S--Yは署名されたメッセージMをSに送信します。

目的: クライアントCはサービスSと話したいと考えています。

  1. クライアントCは、認証用の共有秘密鍵または公開鍵をサービスAに送信します。サービスAの場合、Cはエンドポイントと公開鍵()を認識しています。PKCPKA

  2. A [now + interval | user-id or PKC]SA -> C

    説明:

    サービスAは、現在の日時に有効期限として間隔を追加します。送信されるバッファには、有効期限とユーザーIDが含まれています(有効なIDプロバイダーがある場合)。PKC

    [now + interval | user-id or PKC] = T

    署名します。

    [T]SA

  3. クライアントCは、バックエンドサービスSと通信したいと考えています。

  4. C [[M|[T]SA]SC -> S

    Cは、メッセージMとAから署名されたトークンをサービスSに送信します。

  5. Sは、Cが実際に送信したことを気にし、封筒から読み取ったCの署名を確認します。SC

    Sはトークンの署名を検証します。失敗は、要求が拒否されたことを意味します。SA

    Sはトークンを検証します:user-id/ correctおよびtokendate>=now。Expired tokenは、「tokenexpired」メッセージをクライアントCに送信することを意味します。トークンの署名に誤りがある場合、許可は拒否されます。[T]SAPKC

    (オプション; SはC、余談を承認します)

  6. Sは作業を実行し、クライアントCに送り返します。[M2]SS

これはそれほどオーバーヘッドにはなりません。署名の検証は非常に高速な操作です。

証明書

質問「BouncyCastleを使用したRSAでのC#署名データ」は、送信するメッセージである文字列に署名して検証する方法を示しています。

証明書が必要です。puppetのように構成マネージャーを使用している場合(そうする必要があります!;))、証明書署名要求(CSR)を作成してから、puppetを使用して署名します。

特に認証解除に関するScriptumの投稿

証明書失効要求と呼ばれるものがあります。これは基本的に、取り消されて信頼/使用されない公開鍵の洗濯物リストです。そこに配置して失効をブロードキャストします。これは基本的に、クライアントに別の証明書署名要求ラウンドを実行するように要求することによって機能します。PKC

また、特定のトークンを期限切れにする機能が必要な場合は、トークンTを作成するときに一意のID(UUID / GUID)をトークンに追加し、変更時に同様にブロードキャストされるトークン失効リストを使用して、トークンUUIDを削除するようにします。期限切れ。したがって、サービスは、受信したTが含まれている場合、トークン失効リストもチェックします。

ハッシュベースのトークン

巨人がやっているソフトウェアを見てください。例:共有秘密鍵を使用するAmazonのRESTインターフェース:

Amazon S3 REST APIは、認証にキー付きHMAC(ハッシュメッセージ認証コード)に基づくカスタムHTTPスキームを使用します。リクエストを認証するには、最初にリクエストの選択した要素を連結して文字列を形成します。次に、AWSシークレットアクセスキーを使用して、その文字列のHMACを計算します。非公式には、このプロセスを「要求への署名」と呼び、HMACアルゴリズムの出力を「署名」と呼びます。これは、実際の署名のセキュリティプロパティをシミュレートするためです。最後に、このセクションで説明する構文を使用して、この署名をリクエストのパラメータとして追加します。

アマゾンのスキームについてもっと読む。

上記のSubversion/攻撃ベクトル

于 2012-08-30T07:04:29.470 に答える
-1

選択されたアプローチ:完全にステートレスな認証と非認証

最後に、完全にステートレスなトークンベースの認証と非認証に切り替えるための結論とプロトコルを取得しました。

それを達成する方法は?

まず、これは、アプリケーションに対してステートレストークンベースの認証を行うために必要なものです(ただし、ユーザー認証は、このインベントリを除いて同じように機能します)。

  • アプリケーション登録システム。アプリケーションは、サービスへのアクセスです。これは、「アプリケーションがネット上の一部のサービス(イントラネット、インターネット、クラウドなど)にアクセスすることです。これにより、アプリケーションキーが作成されます(ユーザー認証のためにこれをスキップしてください)。
  • クライアントからサービスへの接続がHTTPS/SSLを使用して暗号化されるようにするサーバー証明書。

これは、アプリケーションを認証するフローです。

  1. クライアントは認証要求を認証サービスに送信します。このリクエストには、アプリケーションキー(AppKey)が含まれている必要があります。

  2. 認証サービスは、以前に送信された要求を受信します。

  3. ここで、認証サービスはアプリケーショントークン(AppToken)を作成します。これは、認証サービスに依存するサービスに対して具体的な認証済みクライアントを追跡するために必要な情報の自己記述型連結です。

  4. AppTokenは、次の複合文字列です(この構成は、JSONを使用してシリアル化されたオブジェクトにすることができます)。

    • アプリケーションハッシュ(*いくつかのアプリケーション情報を連結した結果であるSHA-またはその他-。これは、サービスシークレット+有効期限(トークン自体の一部です)になります。なぜ有効期限ですか?。中間者または何かがセキュリティを破り、トークンの有効期限を変更する可能性がありますか?リクエストを認証するために暗号化されたトークンが復号化されると、有効期限+ AppKeyを再度ハッシュした結果、同じハッシュが生成されなくなるため、トークンは無効になります。
    • 発行日。トークン作成時の現在のUTC日付+時刻。
    • 有効期限。トークンが無効になるUTCDateT+Time。
  5. 認証サービスは、ステップ4の結果(JSONでシリアル化されたオブジェクト)を暗号化します。**対称暗号のキーまたはパスワードとしてAppKeyを使用します。私の場合、そのためにRijndaelを使用します。

  6. プレーンテキストのクレデンシャルの送信を回避するために、後続のリクエストにはこのトークンが含まれます。これらのリクエストには常にAppKeyも含まれるため、認証サービスは、リクエストを認証しようとしているアプリケーションを識別できます。

  7. しばらくすると、トークンの有効期限が切れるか無効になり、クライアントが新しいAppTokenを要求します。または、クライアントがユーザーによって閉じられ、セキュリティトークンを保存する永続ストレージがないため、次のクライアントセッションで必要に応じて新しいトークンが要求されます。


このような認証方法の.NET実装に関するヒントと詳細:

  • System.Security.Cryptography.RijndaelManaged対称暗号化にクラスを使用しました。AppKeyとAppTokenの両方(トークンベースのユーザー認証の場合はほぼ同じソリューションです)は、RijndaelManagedクラスを使用して生成されます。

  • 暗号化されたテキストはHEX文字列に変換されます。これは、認証応答とともに送信されます。この場合(RESTFul API)、AppTokenを表すHEX文字列が応答ヘッダーとして送信されます。リクエストにこのHEX文字列が含まれる場合は常に、認証プロセスによって元の暗号化されたテキストに再変換され、後でトークンが有効かどうかを評価するために復号化されます。


ヘンリックに感謝します。私はあなた自身の答えにいくつかの概念を取り入れ、それらを私自身の結論と混ぜ合わせました。

于 2012-09-04T09:50:11.090 に答える