30

Thinktecture AuthorizationServer (AS) を使用していますが、うまく機能しています。

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

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

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

提案された解決策

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

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

ボタンをクリックしたのでRemember decision、トークンの AS を押すたびに、新しいトークンが自動的に返されます。

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

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

FedAuth Cookie が盗まれたら、私はまだ困ると思います。

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

4

4 に答える 4

6

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

既にご存じのとおり、暗示的許可は、資格情報を秘密にできないコンシューマが使用する必要があります。このため、認可サーバーが発行するアクセス トークンは ttl を制限する必要があります。たとえば、Google は3600 秒でアクセス トークンを無効にします。もちろん、ttl を増やすことはできますが、長期間有効なトークンになることはありません。

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

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

于 2015-07-18T16:29:44.910 に答える
2

あなたの質問を理解できるかどうかわかりませんが、

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

事実を要約すると、

リフレッシュ トークンは、A: Authorization Grant の一部として使用されることがあります。

https://www.rfc-editor.org/rfc/rfc6749#section-1.5

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

https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2

そのため、アクセス トークンを発行するときにリフレッシュ トークンを取得できます (リフレッシュ トークンは常にオプションです)。

https://www.rfc-editor.org/rfc/rfc6749#section-5.1

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

  1. ユーザーがログインし、[決定を記憶] をクリックしたことを確認します (そうでない場合、iframe は機能しません)。
  1. WebAPI を呼び出し、401 応答が返された場合は、以下の手順で新しいトークンを取得してください...
  1. ページに非表示の iframe を配置します。この URL を設定して、認可サーバーから新しいアクセス トークンを取得します。
  1. iframe のハッシュ フラグメントから新しいトークンを取得し、これを SPA に保存して、今後のすべての WebAPI リクエストに使用します。
  1. SPA(あなた)は、ユーザーが決定を記憶することを選択したかどうかわかりません。AS 方向であり、完全なブラックボックスである必要があります。このステップを飛ばす。

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

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

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

  • 遅延、AS が遅い、接続が遅い、または時間制限が厳しすぎる
  • ユーザーは決定を記憶することを選択しませんでした

この場合:

  1. ログインで iframe を表示

AS がリフレッシュ トークンを提供しない場合は、上記のシナリオをお勧めしますが、そのようなすべての AS は記憶オプションも提供しないと思います。

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

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

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

  3. SO がアクセス トークンを使用しようとする

  4. SO は結果を返します + リフレッシュ トークン

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

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

于 2015-06-01T10:38:59.143 に答える
-2

Google o-Auth では、アクセス トークンは 1 時間しか有効ではないため、1 時間ごとにアクセス トークンをプログラムで更新する必要があります。これを行うには、簡単に Web API を作成できます。リフレッシュ トークンが必要です。また、C#コードを使用して、更新トークンの有効期限が切れることはありません。これを行いました。

 if (dateTimeDiff > 55)
            {
                var request = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/oauth2/v3/token");
                var postData = "refresh_token=your refresh token";
                postData += "&client_id=your client id";
                postData += "&client_secret=your client secrent";
                postData += "&grant_type=refresh_token";

                var data = Encoding.ASCII.GetBytes(postData);            
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                request.UseDefaultCredentials = true;

                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();
                string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

            }

アクセストークンの最終更新日時をどこかに保存する必要があります(データベースなど)。リクエストを行う必要があるときはいつでも、現在の日時でそれを差し引くことができます.60分以上の場合は、新しいトークンを取得するには、webapi を呼び出す必要があります。

于 2016-03-21T14:39:14.263 に答える