はじめに
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
token
Response 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_token
value, where the hash algorithm used is the hash algorithm used in thealg
Header Parameter of the ID Token's JOSE Header. For instance, if thealg
isRS256
, hash theaccess_token
value with SHA-256, then take the left-most 128 bits and base64url encode them. Theat_hash
value is a case sensitive string.If the ID Token is issued from the Authorization Endpoint with an
access_token
value, which is the case for theresponse_type
valueid_token token
, this is REQUIRED; it MAY NOT be used when no Access Token is issued, which is the case for theresponse_type
valueid_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_type
valuescode id_token
andcode id_token token
, theiss
andsub
Claim 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_hash
andc_hash
Claims 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
code
value, where the hash algorithm used is the hash algorithm used in thealg
Header Parameter of the ID Token's JOSE Header. For instance, if thealg
isHS512
, hash thecode
value with SHA-512, then take the left-most 256 bits and base64url encode them. Thec_hash
value is a case sensitive string.If the ID Token is issued from the Authorization Endpoint with a
code
, which is the case for theresponse_type
valuescode id_token
andcode 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_type
valuescode token
andcode 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_type
valuescode id_token
orcode 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 入門編』解説動画を公開しました!