web-dev-qa-db-ja.com

OpenID ConnectでのIDトークンの有効期限の意図は何ですか?

OpenID Connectでは、アクセストークンには有効期限があります。認証コードフローの場合、これは通常短い時間(たとえば20分)であり、その後は更新トークンを使用して新しいアクセストークンを要求します。

IDトークンには有効期限もあります。私の質問は、これの意図は何ですか?

更新トークンの有効期限よりも短いIDトークンの有効期限は、最終的に有効期限の切れたIDトークンが有効なアクセストークンを持つことを意味します。

だからあなたはするつもりです:

  • 更新トークンの有効期限よりも長いIDトークンの有効期限を与える、または
  • アクセストークンと同じ有効期限に設定し、有効期限が切れたときに何らかのアクション(何?)を行う、または
  • 受信時にクライアントでIDトークンを消費するだけで、その後の有効期限を無視しますか?

OpenID Connect仕様 は、IDトークンを検証するときに、

"The current time MUST be before the time represented by the exp Claim."

(おそらく)上記の3番目のオプションをサポートします。


[〜#〜] edit [〜#〜]

OpenID ConnectはOAuth2上に構築されるため、以下の補足的な質問に対する答えは OAuth2仕様 にあります。

expires_in
     RECOMMENDED.  The lifetime in seconds of the access token.

関連する質問は、トークンの認証コードを交換するときです。同じ仕様では、次のような応答を受け取る可能性があります。

{
 "access_token": "SlAV32hkKG",
 "token_type": "Bearer",
 "refresh_token": "8xLOxBtZp8",
 "expires_in": 3600,
 "id_token": "eyJhbG[...]"
}

しかし、この場合、「expires_in」は何に関連していますか?アクセストークン、更新トークン、またはIDトークン?

(詳細については、 IdentityServer はこれをアクセストークンの有効期限に設定します)。

75
Appetere

私の質問の背後にある仮定のいくつかが間違っていることを発見したので、私は自分の質問に答えています。

IDトークンは、ユーザーが認証したこと、および結果として誰であるかをクライアントに証明するためのものです。

クライアントは、IDトークンを受け取ると、通常、それをClaimsIdentityに変換するなどの処理を行い、Cookieを使用するなどしてこれを永続化します。

IDトークンは、この使用時点で期限切れになっていない必要があります(発行されたばかりなので、あるはずです)。しかし、この後は再び使用されないため、ユーザーがまだアクティブなセッションを保持している間、期限切れかどうかは関係ありませんクライアントには必要な認証情報があり、ユーザーが再度ログインしなければならないまでのセッションの持続時間について、独自のポリシーを選択できます。

質問をするときの私の間違った仮定は、IDトークンとアクセストークンを一緒に使用する必要があり、したがって両方に有効な有効期限が必要であるというものでした。これはさまざまな理由で間違っています:

  • IDトークンは、クライアントに対する認証専用です(上記の説明を参照)。
  • アクセストークンはクライアントとは関係ありません。これらはリソースへのアクセス用であり、クライアントはリソースを呼び出す必要がある場合にのみそれらを処理します。
  • スタンドアロンMVCまたはWebFormsアプリケーションonlyのようなものにはIDトークンが必要です。外部リソースを呼び出していない場合、アクセスを許可するものがないため、アクセストークンはありません。
69
Appetere

私自身の理由でこれを掘り下げて書き留めなければならなかったので、ここで学んだことをここに投稿します...

最初に、明白なことを述べるリスクで質問に答えます。IDトークンは信頼できないため、現在の時間が有効期限よりも長い場合、そのコンテンツは無視する必要があります。質問者の回答は、ユーザーの最初の認証の後、IDトークンは再び使用されないことを示しています。ただし、IDトークンはIDプロバイダーによってsignedであるため、ユーザーが誰であるかを確実に判別する方法を提供するために、いつでもsefulになる可能性があります。アプリが使用している可能性があります。単純なユーザーIDまたは電子メールアドレスを使用することはreliableではありません。簡単にスプーフィングされる可能性があるため(だれでも電子メールアドレスまたはユーザーIDを送信できます)通常はサードパーティであるという利点もあります)スプーフィングされることはなく、はるかに信頼性の高い認証メカニズムです。

たとえば、モバイルアプリはバックエンドサービスに通知できるようにしたい場合がありますwhoユーザーはアプリを使用しているので、最初の認証後の短い期間後にそうする必要があります。 IDトークンの有効期限が切れているため、ユーザーを確実に認証するために使用できません。

そのため、アクセストークン(承認に使用-アクセス許可ユーザーの所有権を指定)を更新できるように、IDトークンを更新できますか(使用認証用-whoユーザーの指定) OIDC仕様によると、答えは明らかではありません。 OIDC/OAuthには、トークンを取得するための3つの「フロー」、承認コードフロー、暗黙フロー、およびハイブリッドフローがあります(他の2つのバリアントであるため、以下では省略します)。

OIDC/OAuthの暗黙フロー の場合、ブラウザーのユーザーを認証エンドポイントにリダイレクトし、id_token要求パラメーターの値としてresponse_typeを含めることにより、認証エンドポイントでIDトークンを要求します。 暗黙的なフローの成功した認証応答 は、id_tokenを含める必要があります。

認証コードフロー の場合、クライアントは、ユーザーを許可エンドポイントにリダイレクトするときに、response_type要求パラメーターの値としてcodeを指定します。成功した応答には認証コードが含まれます。クライアントクライアントは、承認コードを使用してトークンエンドポイントに要求を行い、 OIDC Core Section 3.1.3.3 Successful Token Response応答にはIDトークンを含める必要がありますを使用します。

どちらのフローでも、最初にIDトークンを取得する方法ですが、どのように更新しますか? OIDCセクション12:更新トークンの使用 には、更新トークンレスポンスに関する次のステートメントがあります。

更新トークンの検証に成功すると、応答本体はセクション3.1.3.3のトークン応答になりますが、にはid_tokenが含まれない場合があります。

はIDトークンを含まない可能性があり、IDトークンを強制的に含める方法が指定されていないため、応答にIDトークンが含まれないと想定する必要があります。したがって、技術的には、更新トークンを使用してIDトークンを「更新」する特定の方法はありません。したがって、新しいIDトークンを取得する唯一の方法は、ユーザーを認証エンドポイントにリダイレクトしてユーザーを再認証/認証し、暗黙的なフローまたは認証コードフローを次のように開始することです上記のとおり。 OIDC仕様では、Prompt要求パラメーターを authorization request に追加しているため、クライアントはrequest許可サーバーがユーザーにUIを要求しませんが、リダイレクトはまだ発生する必要があります。

27
Scott Willeke

それは同じ意図です:有効期限が切れるとid_tokenを使用できなくなります。主な違いは、id_tokenはデータ構造であり、情報はトークン自体にエンコードされるため、サーバーやエンドポイントを呼び出す必要はありません。通常のaccess_tokenは、通常、不透明なアーティファクト(GUIDなど)です。

id_tokenのコンシューマーは、常に(時間)有効性を検証する必要があります。

私はISに100%精通しているわけではありませんが、便利な分野だと思います。 expクレームを常に確認する必要があります。

有効期限は検証の1つにすぎません。 id_tokensもデジタル署名されており、これも検証ですmust perform。

5
Eugenio Pace

this および OpenID Connect Core 1.0仕様 に従って正しく理解すれば、IDトークン自体をセッションを維持するメカニズムとしてCookieに保存し、毎回送信できますクライアントへの認証要求。クライアントは、IDトークンをローカルで、またはプロバイダーの検証エンドポイントを介して検証できます(提供されている場合は、 Googleと同様 )。トークンの有効期限が切れている場合は、URLパラメーターにPrompt=noneを使用する今回を除き、別の認証要求を行う必要があります。また、id_token_hintパラメーターで期限切れのIDトークンを送信するようにしてください。そうしないと、プロバイダーがエラーを返す可能性があります。

したがって、IDトークンの有効期限は当然のように見えますが、Prompt=noneは、ユーザーの介入なしに新しいIDトークンをスムーズに取得できるようにします(もちろん、ユーザーがそのOpenIDからログアウトしている場合を除きます)。

5
Morrowless

TLDR;

IDトークンを検証してから、それが言うことを信頼します。

詳細

OpenID ConnectでのIDトークンの有効期限の意図は何ですか?

クライアントがIDトークンを検証できるようにすることを目的としています。クライアントは、IDトークンの情報を使用する操作の前にIDトークンを検証する必要があります

From OpenID Implicit Flow spec

この文書で定義されている検証手順のいずれかが失敗した場合、正しく検証できなかった情報を必要とする操作は中止しなければならず、検証に失敗した情報は使用してはならない

それを裏付けるために、 GoogleのOpenID Connectドキュメント はIDトークンの検証について次のように述べています。

IDトークンを便利にするものの1つは、アプリのさまざまなコンポーネントにIDトークンを渡すことができるという事実です。これらのコンポーネントは、アプリとユーザーを認証する軽量の認証メカニズムとしてIDトークンを使用できます。 しかし、IDトークン内の情報を使用したり、ユーザーが認証したことをアサーションとして使用したりする前に、検証する必要があります

したがって、クライアントアプリケーションがIDトークンのコンテンツに基づいて何らかのアクションを実行する場合、IDトークンを再度検証する必要があります。

4
Shaun Luttin

トークンの更新とは、ユーザーIS NOT LOGGED IN。の場合でも、承認サーバー(この場合はOP-OpenID-Connectプロバイダー)に何かを要求するために再度使用できることを意味します。これは、限られたリソースに対してのみ、ユーザーがログインして少なくとも1回認証された後にのみ許可します。更新トークン自体も時間的に制限する必要があります。

OIDCで暗黙的なフロー許可エンドポイントを呼び出し、
応答内のIDトークンと、すべてのスコープおよびそれらのすべてのクレーム情報を受け取ります。
APIへの後続の呼び出しは、code flowを使用して行われます。
暗黙フローは、javascriptのみまたはブラウザのみのアプリを有効にすることを目的としています。サーバーと対話するアプリではありません。
したがって、このトークンを「更新」する方法があったとしても、セキュリティ上の観点から、トークンを長生きさせてはいけません。 IDになりすます不正なユーザーによって盗まれ、再利用されます。そのために新しいログインを強制する必要があります。

code flowでは、OPの承認エンドポイントを呼び出して、認可コード(認可トークン、または略してauthcodeとも呼ばれます)。これは、同じ理由で暗黙フローで受け取ったid_tokenと同様に期限切れになるはずであり、更新することはできません。

次に、UIまたはアプリはOPのトークンエンドポイントを呼び出し、(ユーザーがUIを介してOPのサーバー上の所有リソースの使用を許可することをユーザーがさらに同意した後)を受け取ります:

  • Id_token、認証用-これは、サーバーの呼び出しで再び使用されるべきではありません。ただし、ログアウト中のヒントとしては、その有効期限はもう重要ではないため、上記の理由により、有効期限が切れてリフレッシュされることはありません。
  • Access_token-後でAPIを呼び出すときに、OPのUserInfoエンドポイントに与えることができます。これによりクレームが返され、APIはそれに応じて承認できます。

このaccess_tokenは、ユーザーがどのクレームを持っているか、およびユーザーがあなたに与えることに同意したリソース(スコープと各スコープのクレーム)だけをAPIに伝えるため、更新できます。上記で説明したように、これはユーザーがログインしなくなった後でもアクセスを許可するためです。もちろん、ログインせずになりすましを許可したくないので、id_tokenの更新を許可したくありません。

4
pashute

この回答をコメントとして投稿したかったのですが、StackOverflowにあまり積極的ではなかったため、別の回答として投稿していると思います。

また、ユーザーをセッションからログアウトするときにid_tokenとしてid_token_hintを使用します http://openid.net/specs/openid-connect-session-1_0.html =。特定のユーザーのログアウトのみを懸念しているため、id_tokenがこの時点で期限切れになっても、本当に重要だとは思いません。

3
dgonee