web-dev-qa-db-ja.com

更新トークンをクライアントのどこに保存しますか?

私のSPAアプリケーションは、次のアーキテクチャ( source )を使用しています。

enter image description here

これは、ユーザー資格情報(電子メール/パスワードなど)が存在しない場合に新しいアクセストークンを要求する必要があるため、クライアントアプリケーションが更新トークンを知っていることを前提としています。

私の質問:クライアント側のアプリケーションのどこに更新トークンを格納しますか?SOに関するこのトピックについて多くの質問/回答がありますが、リフレッシュトークンの答えは明確ではありません。

アクセストークンと更新トークンは機密データの場所ではないため、ローカル/セッションストレージに保存しないでください。したがって、アクセストークンhttpOnly cookieに保存し(CSRFがある場合でも)、ほとんどのリクエストで必要になります。とにかくリソースサーバーに。

しかし、リフレッシュトークンはどうですか?(1)リソースサーバーへのすべてのリクエストでも送信されるため、Cookieに保存できません。これにより、CSRFに対しても脆弱になります。(2)同じ攻撃ベクトルでアクセス/リフレッシュトークンの両方を公開して送信します。

私が考えることができる3つの解決策があります:


1)リフレッシュトークンをメモリ内のJavaScript変数に格納することには、2つの欠点があります。

  • a)XSSに対して脆弱です(ただし、ローカル/セッションストレージほど明白ではない場合があります)
  • b)ユーザーがブラウザのタブを閉じると、「セッション」が失われます

特に後者の欠点は、悪いUXとして判明します。


2)アクセストークンをセッションストレージに保存し、Bearer access_token承認ヘッダーを介してリソースサーバーに送信します。次に、リフレッシュトークンにhttpOnly Cookieを使用できます。これには、私が考えることができる1つの欠点があります。

  • a)更新トークンは、リソースサーバーに対して行われるすべての要求でCSRFに公開されます。

3)両方のトークンをhttpOnly Cookieに保持します。これには、両方のトークンが同じ攻撃ベクトルにさらされるという前述の欠点があります。


多分私の言及された欠点(別の方法で私に知らせてください)よりも別の方法またはそれ以上がありますが、結局すべてがに要約されます私は更新トークンをクライアント側に保持しますかhttpOnly cookieか、メモリ内のJS変数ですか?前者の場合、アクセストークンはどこに置くのですか?

トピックに精通している人から、これを最善の方法で行う方法についての手がかりを得れば、非常にうれしいでしょう。

8
Robin Wieruch

暗号化されたトークンをHttpOnly Cookieに安全に保存できます。

https://medium.com/@sadnub/simple-and-secure-api-authentication-for-spas-e46bcea592ad

長持ちする更新トークンについて心配する場合。保管をスキップして、まったく使用しないでください。アクセストークンをメモリに保持し、アクセストークンの有効期限が切れたときにサイレントサインインを行うだけです。

廃止 であるため、Implicitフローを使用しないでください。

SPAの認証の最も安全な方法は PKCEを使用した認証コード です。

一般に、自分で何かを構築するよりも、 oidc-client に基づく既存のライブラリを使用する方が適切です。

5
Vladimir Serykh

最適な認証アーキテクチャを使用していません。 SPAはパブリッククライアントであり、クライアントシークレットやリフレッシュトークンなどの情報を安全に保存できません。 Implicit Flow に切り替える必要があります。ここで、 リフレッシュトークンは使用されません です。ただし、代わりに サイレント認証 (サイレント更新)を使用できます。

私は OIDC認定ライブラリ を使用することをお勧めします。私の好きなもの: https://github.com/damienbod/angular-auth-oidc-client

1
Jan Garaj

OAuthは、承認コード、暗黙的、リソース所有者のパスワード資格情報、およびクライアント資格情報の4つの付与タイプを定義します。また、追加の付与タイプを定義するための拡張メカニズムも提供します。

__ RFC 6749-OAuth 2.0 Authorization Framework


Authorization Codeプロセスは本質的に、安全なクライアントで使用するように設計されています。 Client Secretを内部に保持するのに十分に保護されたサーバークライアントがその秘密を保持するのに十分安全である場合は、Refresh TokenClient Secretと同じ安全なストレージに置くだけです。

これは、User-Agent(UA)でホストされているアプリケーションには当てはまりません。それらについては、仕様では、Access Token記号の後のフラグメントでRedirection URIの後に#を表すImplicit付与タイプの使用を推奨しています。 User-Agentで直接トークンを受け取っている場合、それは本質的に安全でない方法であり、そのユーザーエージェントのセキュリティルールに従うことを除いて、それに対してあなたができることは何もありません。

アプリケーションの使用を特定のユーザーエージェントに制限することもできますが、簡単に改ざんできます。トークンをCookieに保存することもできますが、UAが一般的なセキュリティ基準を順守していない場合にもアクセスできます。 UAによって実装および提供されている場合はトークンをローカルストレージに保存できますが、標準を順守している場合も同様です。

これらの暗黙的な間接承認の鍵は、UAへの信頼です。それ以外の場合は、制御された環境(アプリケーションのサーバー)に安全かつ安全に格納されたシークレットが必要なため、最も安全な付与タイプは承認コードです。

暗黙の呼び出しを使用する以外に選択肢がない場合は、根性に基づいて、ユーザーがセキュリティプロトコルに従う安全なUAを使用することを信頼してください。いかなる方法でも、ユーザーのUAの不適切な選択について責任を負いません。

0
Cunning