web-dev-qa-db-ja.com

JWTアクセストークンと更新トークン

App1とApp2の2つのアプリケーションがあります。ユーザーはブラウザを使用してアプリと通信します。 App1は異なる認証をサポートしています。メカニズム(SSO、usr/pwdなど)ですが、App2は認証データにアクセスできず、認証をサポートしていません。機構。したがって、App2がアクセス制御を適用するための承認メカニズムを提供する必要があります。この問題については、SSOとJWTについて考えました。つまり:

  1. App1は認証の役割を果たします。サーバー、およびユーザーがApp2に接続する場合は常に、認証のためにApp1にリダイレクトされます。
  2. 認証が成功すると、App1によってJWTトークンが生成されます(トークンにはuser_idとuser_roleが含まれています)。
  3. トークンがヘッダーに設定され、ユーザーはApp2にリダイレクトされます。

すべての通信が[〜#〜] https [〜#〜]を介して行われ、PKIがトークンの署名に使用されると仮定すると、以下が私の質問です。

  1. App2による簡単な署名検証で十分ですか?または、検証のためにApp1にトークンを送信する必要があります(App2の公開鍵のホワイトリストがあります)?
  2. 30分の有効期限を追加することを検討していますが、クライアント側で更新トークンをどのように処理する必要がありますか?
  3. 生成リフレッシュトークンの代わりに、アクセストークンは1回限りであり、App2はサーバー側でセッションを作成する(トークンのデータを使用)と言っても安全ですか?

手伝ってくれてどうもありがとう :)

3
sgres

これはごく一般的な状況であり、ソリューションがよく知られ、議論され、テストされていることを意味するため、これは良いことです。

  1. App2による簡単な署名検証で十分ですか?または、検証のためにApp1にトークンを送信する必要があります(App2の公開鍵のホワイトリストがあります)?

正解です。トークンを検証するためにApp2が実行する必要があるのは、「単純な」署名検証だけです。これにより、a。)トークンがApp1によってディスペンスされ、b。)トークン内のクレーム(キーと値のペア)が改ざんされていないことが保証されます。

  1. 30分の有効期限を追加することを検討していますが、クライアント側で更新トークンをどのように処理する必要がありますか?

これは個人の好みによりますが、更新トークンは好きではありません。更新トークンは遠い将来の有効期限(つまり、数日または1週間)を意味し、盗まれた場合は非常に損害を与える可能性があります。さらに、私の経験では、クライアント側にシークレットを格納するための本当に良い方法はありません。 Cookieは安全ではなく、クライアント側のDBの方がはるかに優れているとは思いません。ユーザーパスワードで暗号化することもできますが、その場合はユーザーがパスワードを再入力する必要があるため、リフレッシュトークンの目的に反します。そのため、可能な場合は更新トークンを回避します。

  1. 生成リフレッシュトークンの代わりに、アクセストークンは1回限りであり、App2はサーバー側でセッションを作成する(トークンのデータを使用)と言っても安全ですか?

この計画には欠陥はありません。更新トークンに依存するよりもはるかに安全です。ここでの唯一の注意点は、App1のアクセストークンを無効にする機能があることを確認することです。言い換えると、App1に対して認証を行ってから、トークンを取得してからApp2にアクセスし、認証を行ってセッションIDを取得すると、満足です。しかし、攻撃者が私のブラウザのCookieから私のトークンを盗む可能性があります。攻撃者は、トークンがまだ期限切れになっていない限り、このトークンを使用して、App2で私の資格情報を使用して自分のセッションを取得できます。したがって、このシナリオでは、App1とApp2が通信できる必要があります。 App2は、App1がトークンがまだ使用されていないことを示していることを確認します。 App2はそれを使用し、次にApp1にそれが使用されたことを伝えます。トークンを無効にして、別のセッションIDを生成するための将来のリクエストで再利用できないようにしてください。

ご覧のとおり、これはさらに複雑になります。ただし、これを行わない場合、実際にはワンタイムトークンを使用していません。別の方法としては、トークンの有効期限を非常に短く(つまり、5分以内)し、ユーザーがリダイレクトされてApp2で認証され、継続的な認証のためにセッションIDを取得するのに十分な時間を確保します。これはより簡単なルートかもしれませんが、実際にここに到達したいセキュリティのレベルに依存しています。

どちらにしても、セッションIDは賢い考えです。リクエストごとにトークンの署名を常に再チェックする必要がないため、App2サーバーの負荷が軽減される可能性があります。

1
dFrancisco

開発者として

APP 1がフェデレーションサービスとして構築されていない限り、APP1をフェデレーションサービスとして機能するように拡張するべきではありません。これは単に悪いソフトウェア設計です。

APP2に認証と承認がない場合は、論理的にそれをアプリケーションに追加するだけです。これはSSO方式でもかまいませんが、認証/承認を行うように設計されたサービスで認証されていることを確認してください。

APP1とAPP2が相互に関係がない場合(そのように聞こえます)、依存関係を作成しないでくださいVIA AUTHENTICATION。

セキュリティ専門家として

あなたの質問に答えるには:

  1. これは、リスクと、これらのアプリケーションが組織にとってどれほど重要かによって異なります。 JWTについてもう一度お読みください。トークンを検証するには、シークレットが必要であり、設計ではAPP1にそれがあり、APP2にもそれを保持する(リスクをさらす)か、APP1に依存してトークンを検証する必要があります。自分自身「なぜAPP 1はAPP 2のトークンが有効かどうかを気にするのですか?」答えは、APP 1がAPP 2の安全性に責任を持つように、不要な依存関係を構築したためです。
  2. トークンの性質上、それらをクライアント側で処理することはありません。トークンが更新されない場合、トークンの有効期限が切れると、それはダメです。それを拒否する必要があります。更新トークンは、有効期限に達したときに新しい認証トークンを生成するために使用されます。 30分の更新トークンは、30分後に完全に再認証する必要があることを意味します。それが目的の場合は、更新トークンを使用せず、30分の認証トークンを用意してください。
  3. トークンシステムの目的は、アプリケーションから状態を削除することです。セッションを実行する場合は、セッションを実行してトークンを無視してください。 APP 2認証でワンタイムパスワードを実行する場合、OTPを実行するよりも、両方のリスクがあり、両方の正当な理由がないため、両方にとって恐ろしいことです。セッションとトークン認証について読みます。

あなたの質問に基づくこれについての私の意見-それはセキュリティ管理、IT管理、そして開発管理の悪夢になるでしょう、認証サービスのために別の独立したアプリに依存する独立したアプリがあります。

ストーリーにはまだまだあると思いますが、これについて意思決定をしていると、「なぜこれが理にかなっているのか説明していただけますか?」コメント。

3
Shane Andrie