web-dev-qa-db-ja.com

シングルページアプリの更新アクセストークンを使用したOauth2暗黙フロー

Thinktecture AuthorizationServer(AS)を使用していますが、正常に機能しています。

WebAPIを直接呼び出すことができるネイティブJavaScriptシングルページアプリを作成したいのですが、暗黙的なフローでは更新トークンが提供されません。

AJAX呼び出しが行われた場合、トークンの有効期限が切れていると、APIはログインページにリダイレクトを送信します。データは動的ポップアップを使用しているため、ユーザーに割り込むことになります。

FacebookまたはStackoverflowはどのようにこれを行い、ページで実行されているJavaScriptがAPIを呼び出すことを許可しますか?

提案された解決策

以下のシナリオは理にかなっているように聞こえますか(これはiframeで実行できると仮定しています):

私のSPAは私をASに誘導し、ImplicitFlowによってトークンを取得します。 AS内で、[許可] Read dataスコープをクリックし、Remember decisionをクリックしてから、Allowボタンをクリックします。

Remember decisionボタンをクリックしたので、トークンのASを押すたびに、サインインしなくても新しいトークンが自動的に返されます(FedAuth cookieが表示され、これが私の決定を記憶しており、これにより、ただ動作します)。

私のSPA(信頼できないアプリ)では、更新トークンはなく、アクセストークンしかありません。代わりに私は:

  1. ユーザーがログインして[決定を記憶]をクリックしたことを確認します(そうでない場合、iframeは機能しません)
  2. 以下の手順で401応答が新しいトークンを取得しようとした場合は、WebAPIを呼び出します...
  3. ページに非表示のiframeを配置します。これにより、認証サーバーから新しいアクセストークンを取得するためのURLを設定します。
  4. Iframeのハッシュフラグメントから新しいトークンを取得し、これをSPAに保存して、今後のすべてのWebAPIリクエストに使用します。

FedAuth cookieが盗まれた場合、私はまだ問題を抱えていると思います。

上記のシナリオの標準または推奨される方法はありますか?

30
g18c

あなたの問題は、アクセストークンの有効期限が切れると、認証サーバーのログインページにリダイレクトされることにより、ユーザーが中断を経験することだと理解しています。しかし、少なくとも暗黙の許可を使用する場合は、これを回避できるとは思いません。

すでにご存知のとおり、 暗黙の付与 は、資格情報を秘密に保つことができない消費者が使用する必要があります。このため、認証サーバーによって発行されるアクセストークンのttlは制限されている必要があります。たとえば、グーグルは 600秒 でアクセストークンを無効にします。もちろん、ttlを増やすことはできますが、長寿命のトークンになることはありません。

また、私の意見では、ユーザーの中断はごくわずかです。つまり、正しく実装されていれば、ユーザーは認証サーバーで1回認証するだけで済みます。それを行った後(たとえば、ユーザーが制御するリソースへのアプリケーションアクセスを初めて許可する場合)、セッションが確立され(Cookieベースまたはトークンベースのいずれか)、コンシューマーのアクセストークン(暗黙の許可を使用するWebアプリ)が確立されます。有効期限が切れると、トークンの有効期限が切れたことがユーザーに通知され、認証サーバーによる再認証が必要になります。ただし、セッションはすでに確立されているため、ユーザーはすぐにWebアプリにリダイレクトされます。

ただし、これが希望どおりでない場合は、iframeで複雑な処理を行うのではなく、認証コードの付与を使用することを検討する必要があります。その場合、資格情報を秘密にして更新トークンを使用できるため、サーバー側のWebアプリケーションが必要です。

5
danillouz

アクセストークンの有効期限が切れた場合にリクエストをキューに入れる必要があるようです。これは多かれ少なかれFacebookとGoogleがそれを行う方法です。 Angularを使用する簡単な方法は、HTTPインターセプターを追加し、HTTP401応答を確認することです。1つが返された場合は、再認証し、認証要求が完了するまで、その後に着信するすべての要求をキューに入れます。 (つまり、promise)。それが完了すると、更新トークンを使用して、認証要求から新しく返されたアクセストークンで未処理のキューを処理できます。

ハッピーコーディング。

3

私があなたの質問を理解しているかどうかはわかりませんが、

WebAPIを直接呼び出すことができるネイティブJavaScriptシングルページアプリを作成したいのですが、暗黙的なフローでは更新トークンが提供されません。

事実を要約し、

更新トークンは、A:AuthorizationGrantの一部として使用されることがあります。

https://tools.ietf.org/html/rfc6749#section-1.5

暗黙のフローで述べたように、更新トークンは返されませんが、承認付与の部分でのみ取得されます

https://tools.ietf.org/html/rfc6749#section-4.2.2

したがって、アクセストークンを発行するときに更新トークンを取り戻すことができます(更新トークンは常にオプションです)

https://tools.ietf.org/html/rfc6749#section-5.1

私のSPA(信頼できないアプリ)では、更新トークンはなく、アクセストークンしかありません。代わりに私は:

1)ユーザーがログインし、[決定を記憶する]をクリックしたことを確認します(そうでない場合、iframeは機能しません)

2)以下の手順で401応答が新しいトークンを取得しようとした場合は、WebAPIを呼び出します。

3)ページに非表示のiframeを配置します。これにより、AuthorizationServerから新しいアクセストークンを取得するためのURLを設定します。

4)iframeのハッシュフラグメントから新しいトークンを取得し、これをSPAに保存して、今後のすべてのWebAPIリクエストに使用します。

1)SPA(あなた)は、ユーザーが選択した記憶の決定かどうかわかりません。 AS方向にあり、完全なブラックボックスである必要があります。このステップを飛ばす。

2)いつでも、アクセストークンを使用して、結果を待つことができます。

3)アクセストークンの有効期限が切れていて、更新トークンがない場合でも、非表示のiframeを作成して、新しいアクセストークンの取得を試みることができます。

4)ASが決定を記憶し、将来変更しないオプションを提供すると仮定します。次に、iframeはユーザーの操作なしで新しいアクセストークンを取得し、未知の制限時間内に結果を取得します。結果は、読み取り固有のCookieまたはiframe setIntervalについてpostmessageで確認できます。制限時間内にデータを取得しない場合は、次のシナリオのいずれかが発生しました。

  • ラグ、ASが遅い、接続が遅い、または制限時間が厳しすぎる
  • ユーザーが決定を覚えることを選択しなかった

この場合:

5)ログインでiframeを表示する

ASが更新トークンを提供しない場合は、上記のシナリオをグッドプラクティスと見なしますが、そのようなすべてのASは記憶オプションも提供しないと思います。

StackOverflow <---> Googleシナリオ(推測しかできません)

1)ユーザーログイン、認証リクエストが発生しました

2)ユーザーがログインし、SOアクセストークンを取得します

3)SOアクセストークンを使用しようとします

4)SO結果を取得+トークンを更新

5)SO更新トークンを保存します

6)SOはユーザーのGoogleアカウントに永続的にアクセスできます

2
Entity Black