web-dev-qa-db-ja.com

OAuth 2つのアクセストークンと更新トークンを保持する必要がある理由

OAuth 2:更新トークンをデータベースに永続化することになると、一部の作成者はアクセストークンも保存することを好むか、少なくともそれを何かとして言及します。そして、refresh_tokenに基づいてアクセスを許可することになると、チケットがデータベースから取得され、非シリアル化され、更新されて、新しい更新トークンでユーザーに送信されます。

RefreshTokensテーブルの例を次に示します。ここで、ProtectedTicket列はシリアル化されたaccess_tokensをユーザーに発行します。

enter image description here

これまでのところ、このアプローチには少なくとも3つの理由があります。

  1. ユーザーのアクセスチケットを保持し、誰かがそれらを取得するのを待って、不審なリソースサーバーに再利用する場合、それはセキュリティ上の脅威ではありませんか?一方向ハッシュは使用できません。これは、逆シリアル化、更新、およびユーザーへの送信が必要であり、有効なアクセストークンも保持したくないためです。

  2. たとえば、万が一に備えて、チケットのシリアライズ/デシリアライズに使用される暗号化キーを時々更新したいとします。 access_tokenが期限切れになったときにユーザーをログオフさせたくない場合は、永続化されたチケットの更新に注意する必要があります。

  3. #1#2の懸念度に応じて、コードのチャンクを記述する必要があります。多分あなたはあなたの周りにいくつかの汚いハックを実装するOAuthそれはあなたが必要とする拡張ポイントを提供しないかもしれないのでフレームワークです。

それで問題は、なぜあなたはそれをすべてしたいのですか?面倒なことを本当にやる価値のある利点は何でしょうか? easiersaferなどmaintainableを確認したら、refresh_tokenを確認したら、新しいチケットを作成できますか?

10
2ooom

accessTokenをハッシュするポイントは何ですか?

ユーザーはどこでもパスワードを再利用するため、パスワードをハッシュ化します。パスワードを再利用しない場合、パスワードをハッシュする必要はありません。アプリケーションは結局ハッキングされているため(攻撃者がデータベースにアクセスしたため)、すべてがすでに失われています。

accessTokensは再利用されません。セキュリティに追加すると、一度だけ使用されます(たとえば、トークンの有効期間に応じて10分間)。では、なぜそれらをハッシュする必要があるのでしょうか。 RefreshTokensを使用して複数のaccesstokenを取得できます。これは、それらをハッシュすることが合理的であるように思われる理由ですが、refreshTokensはアプリケーション間で使用されないため、それでも問題はありません。

本当に必要な場合は、accessTokenの暗号化について考えるかもしれませんが、暗号化キーを含め、アプリケーション全体がハッキングされていると考えられます。ちなみに、実際にアクセストークンを保存するのではなく、チケットを保存してアクセストークンを取得しますが、質問の関連性は変わりません。

7
Michael

答えはおそらくパフォーマンスに関連しています。

OAuth2アクセストークンは有効期間が短くなるように設計されていますが、更新トークンは新しいアクセストークンを取得するために使用できるため、有効期間が長くなるように設計されています。ほとんどのクライアントライブラリは、認証サーバーにアクセスしないようにOAuthアクセストークンをキャッシュするように設計されています。ここを参照してください:

https://github.com/google/google-api-dotnet-client/blob/master/Src/Support/GoogleApis.Auth/OAuth2/UserCredential.cs

/// <summary>
/// Default implementation is to try to refresh the access token if there is no access token or if we are 1 
/// minute away from expiration. If token server is unavailable, it will try to use the access token even if 
/// has expired. If successful, it will call <see cref="IAccessMethod.Intercept"/>.
/// </summary>
        public async Task InterceptAsync(HttpRequestMessage request, CancellationToken taskCancellationToken)
[...]

Google OAuth2 Playgroundにアクセスすると、実際の動作を確認できます: https://developers.google.com/oauthplayground/

APIを承認するとき(カスタムスコープに「プロファイル」と入力して、リストをクリックしたくない場合は、[APIの承認]をクリックしてみてください)、認証交換を行い、アクセス/更新トークンを受け取った後、次のように表示されます。

「アクセストークンは[カウントダウン]秒で期限切れになります。

[]有効期限が切れる前にトークンを自動更新します。」

アクセストークンをキャッシュまたは保存することにより、承認サーバーに往復してリフレッシュトークンをアクセストークンと交換する必要がなくなります(遅延と承認サーバーの停止から保護します)。一部のサーバーでは、リフレッシュトークンをアクセストークンと交換できる頻度を制限する場合もあります(たとえば、アクセストークンの生成には、「高価な」暗号化操作が含まれる場合があります)。

アクセストークンの漏えいは、それを許可した人の身元を主張するために他の情報なしで使用できるという意味で「悪い」-しかし、アクセストークンの寿命が限られているという事実によって多少緩和され、攻撃者はすぐに手を傾ける/値を使用します。更新トークンを漏らすことは、(理論的には)永続的なアクセスを許可するため、「悪い」ただしこれをより複雑にするのは、更新を実行することです<->アクセストークンの交換には、OAuth2 client_secretの知識も必要です。

あなたが説明している現在のモデルでは、ProtectedTicketが暗号化されているかどうかは不明です(シリアル化されていると言及していますが、後で永続化チケットの更新について話します)。データベース内のアクセストークンを暗号化して、管理データベースアクセスを持つユーザーによる(誤用)から保護する場合は、バージョン付きキーを処理するためのソリューションを確認できます。これにより、暗号化キーをローテーションできます。私がよく知っているのは https://github.com/google/keyczar で、誰かがこれのために.NETバインディングを作成しました(私はあなたのスクリーンショットから.NET上にいると想定しています)。

KeyCzarは、懸念事項のいくつかに対処する簡単な方法を提供する場合がありますが、システムの実際のセキュリティプロパティの多くは、脅威モデルとデータベーススキーマ以外の多くの要因に依存します。

1
Phil Ames