はじめに
OpenID Connect は OAuth 2.0 を拡張する形で策定されました。
OAuth 2.0 はアクセストークン発行手順に関する仕様で、**RFC 6749(The OAuth 2.0 Authorization Framework)**で定義されています(参考:一番分かりやすい OAuth の説明)。
一方、OpenID Connect は ID トークン発行手順に関する仕様で、主要部分は OpenID Connect Core 1.0 で定義されています(参考:一番分かりやすい OpenID Connect の説明)。
RFC 6749 は**認可エンドポイント**という Web API を定義しています。 この API は必須のリクエストパラメーターとして response_type を要求します。 OpenID Connect は、この response_type の仕様を拡張することにより ID トークン発行手順を定義しました。
RFC 6749 の時点では response_type が取りうる値は code か token のどちらかでしたが、OpenID Connect では、id_token という新しい値を追加した上で、code、token、id_token の任意の組み合わせを response_type に指定してもよいことにしました。 加えて、none という特殊な値も定義しました。 この結果、response_type は次の値を取りうることになりました。
response_type |
|
|---|---|
| 1 | code |
| 2 | token |
| 3 | id_token |
| 4 | id_token token |
| 5 | code id_token |
| 6 | code token |
| 7 | code id_token token |
| 8 | none |
以降、response_type の値ごとにフローを紹介します。
なお、ID トークンの発行を要求するリクエストは、scope リクエストパラメーターに openid という値を含める必要があります。 特に、scope に openid を含めていないと、response_type=code のケースは RFC 6749 の認可コードフローそのものとして扱われ、ID トークンは発行されないので注意してください。 response_type=code token についても同様のことが言えます。
1. response_type=code
response_type の値が code の場合、これだけでは RFC 6749 の認可コードフローと何も変わりません。 しかし、scope に openid が含まれている場合、トークンエンドポイントから、アクセストークンに加えて ID トークンも発行されます。
scope に openid が含まれる場合
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | 発行 | X | X |
| トークンエンドポイント | X | 発行 | 発行 |
scope に openid が含まれない場合(RFC 6749 の認可コードフロー)
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | 発行 | X | X |
| トークンエンドポイント | X | 発行 | X |
2. response_type=token
response_type の値が token の場合、これは RFC 6749 のインプリシットフローそのものです。 scope に openid が含まれていたとしても ID トークンは発行されません。
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | X | 発行 | X |
OpenID Connect では token という応答タイプを使わないことは、OpenID Connect Core 1.0 の「3. Authentication」の末尾に明示的に書かれています。
NOTE: While OAuth 2.0 also defines the
tokenResponse Type value for the Implicit Flow, OpenID Connect does not use this Response Type, since no ID Token would be returned.
3. response_type=id_token
response_type が id_token の場合、認可エンドポイントから ID トークンが発行されます。 このフローではトークンエンドポイントは使われません。
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | X | X | 発行 |
4. response_type=id_token token
response_type が id_token token の場合、認可エンドポイントからアクセストークンと ID トークンが発行されます。 このフローではトークンエンドポイントは使われません。
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | X | 発行 | 発行 |
認可エンドポイントから ID トークンと共にアクセストークンを発行する場合、ある方法で計算されたアクセストークンのハッシュ値を ID トークンに埋め込む必要があるので、このフローを実装する際は注意してください。 OpenID Connect Core 1.0 の「3.2.2.10. ID Token」には次のように書かれています。
at_hash
Access Token hash value. Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the
access_tokenvalue, where the hash algorithm used is the hash algorithm used in thealgHeader Parameter of the ID Token's JOSE Header. For instance, if thealgisRS256, hash theaccess_tokenvalue with SHA-256, then take the left-most 128 bits and base64url encode them. Theat_hashvalue is a case sensitive string.If the ID Token is issued from the Authorization Endpoint with an
access_tokenvalue, which is the case for theresponse_typevalueid_token token, this is REQUIRED; it MAY NOT be used when no Access Token is issued, which is the case for theresponse_typevalueid_token.
5. response_type=code id_token
response_type が code id_token の場合、認可エンドポイントから認可コードと ID トークンが、トークンエンドポイントからアクセストークンと ID トークンが発行されます。
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | 発行 | X | 発行 |
| トークンエンドポイント | X | 発行 | 発行 |
認可エンドポイントとトークンエンドポイントの両方から ID トークンが発行されますが、双方の ID トークンの内容は必ずしも同じとは限りません。 これについて OpenID Connect Core 1.0 の「3.3.3.6 ID Token」で次のように述べられています。
If an ID Token is returned from both the Authorization Endpoint and from the Token Endpoint, which is the case for the
response_typevaluescode id_tokenandcode id_token token, theissandsubClaim Values MUST be identical in both ID Tokens. All Claims about the Authentication event present in either SHOULD be present in both. If either ID Token contains Claims about the End-User, any that are present in both SHOULD have the same values in both. Note that the OP MAY choose to return fewer Claims about the End-User from the Authorization Endpoint, for instance, for privacy reasons. Theat_hashandc_hashClaims MAY be omitted from the ID Token returned from the Token Endpoint even when these Claims are present in the ID Token returned from the Authorization Endpoint, because the ID Token and Access Token values returned from the Token Endpoint are already cryptographically bound together by the TLS encryption performed by the Token Endpoint.
認可エンドポイントから ID トークンと共に認可コードを発行する場合、ある方法で計算された認可コードのハッシュ値を ID トークンに埋め込む必要があるので、このフローを実装する際は注意してください。 OpenID Connect Core 1.0 の「3.3.2.11. ID Token」には次のように書かれています。
c_hash
Code hash value. Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the
codevalue, where the hash algorithm used is the hash algorithm used in thealgHeader Parameter of the ID Token's JOSE Header. For instance, if thealgisHS512, hash thecodevalue with SHA-512, then take the left-most 256 bits and base64url encode them. Thec_hashvalue is a case sensitive string.If the ID Token is issued from the Authorization Endpoint with a
code, which is the case for theresponse_typevaluescode id_tokenandcode id_token token, this is REQUIRED; otherwise, its inclusion is OPTIONAL.
6. response_type=code token
response_type が code token の場合、認可エンドポイントから認可コードとアクセストークンが発行され、トークエンドポイントからアクセストークンが発行されます。 加えて、scope に openid が含まれる場合は、トークンエンドポイントから ID トークンも発行されます。
scope に openid が含まれる場合
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | 発行 | 発行 | X |
| トークンエンドポイント | X | 発行 | 発行 |
scope に openid が含まれない場合
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | 発行 | 発行 | X |
| トークンエンドポイント | X | 発行 | X |
認可エンドポイントとトークンエンドポイントの両方からアクセストークンが発行されますが、双方のアクセストークンは必ずしも同じとは限りません。 これについて OpenID Connect Core 1.0 の「3.3.3.8. Access Token」に次のように書かれています。
If an Access Token is returned from both the Authorization Endpoint and from the Token Endpoint, which is the case for the
response_typevaluescode tokenandcode id_token token, their values MAY be the same or they MAY be different. Note that different Access Tokens might be returned be due to the different security characteristics of the two endpoints and the lifetimes and the access to resources granted by them might also be different.
7. response_type=code id_token token
response_type が code id_token token の場合、認可エンドポイントから認可コード、アクセストークン、ID トークンが発行され、トークエンドポイントからアクセストークンと ID トークンが発行されます。
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | 発行 | 発行 | 発行 |
| トークンエンドポイント | X | 発行 | 発行 |
認可エンドポイントとトークンエンドポイントの両方からアクセストークンが発行されますが、双方のアクセストークンは必ずしも同じとは限りません。 これは「6. response_type=code token」と同様です。 仕様については OpenID Connect Core 1.0 の「3.3.3.8. Access Token」を参照してください。
認可エンドポイントから ID トークンを発行する際、アクセストークンも共に発行する場合は当該アクセストークンのハッシュ値を、認可コードも共に発行する場合は当該認可コードのハッシュ値を、ID トークンに埋め込む必要があります。 これは「4. response_type=id_token token」や「5. response_type=code id_token」と同様です。 仕様については OpenID Connect Core 1.0 の「3.3.2.11. ID Token」を参照してください。
8. response_type=none
response_type が none の場合、認可エンドポイントからは何も発行されません。 このフローではトークンエンドポイントは使われません。
| 認可コード | アクセストークン | ID トークン | |
|---|---|---|---|
| 認可エンドポイント | X | X | X |
none の定義自体は OAuth 2.0 Multiple Response Type Encoding Practices の「4. None Response Type」にあります。
9. サポート状況
OpenID Connect サポートを謳っているソフトウェアが上記全てのフローをサポートしているとは限りません。 OpenID Certification 取得済みの OpenID プロバイダーの実装に限っても、約半数は Hybrid OP プロファイルを取得していないので(=ハイブリッドフローをサポートしていないので)、全フローをサポートしている OpenID プロバイダーの実装はむしろ少数派と考えてよいでしょう。
OpenID Foundation の Financial API ワーキンググループが仕様策定中の Financial API では、更新系 API を利用するためのアクセストークンを取得するためには、response_type の値を code id_token もしくは code id_token token として認可リクエストを投げなければなりません。 Financial Services – Financial API - Part 2: Read and Write API Security Profile の「5.2.2. Authorization Server」)には次のように書かれています。
shall require the
response_typevaluescode id_tokenorcode id_token token;
これはつまり、Financial API への準拠を考えているのであれば、OpenID Connect のハイブリッドフローをサポートしている認可サーバーを使用する必要があるということです。 世の中には response_type=code しかサポートしていない OpenID Connect 実装も実在するので、認可サーバー選択の際は注意してください。
追記:2019 年 4 月 20 日
2018 年 10 月に承認された FAPI 第二版では、JARM を使う場合、ID トークンを Detached Signature として用いる必要がなくなるため、更新系 API 用アクセストークンを要求する場合でも、response_type に id_token を含めなくてもよくなります。詳細は『【2019年版】世界最先端の API セキュリティー技術、実装者による『FAPI(Financial-grade API)』解説』の『2.5. Part 2: JARM』を参照してください。
おわりに
こんな複雑なもの実装していられない、と思った方は Authlete(オースリート)の利用をご検討ください!(参考:OAuth 2.0 / OIDC 実装の新アーキテクチャー)
追記:2020 年 3 月 20 日
この記事の内容を含む、筆者本人による『OAuth & OIDC 入門編』解説動画を公開しました!









