🎉

OIDC と JWT の関わり - Oauth2.0 との違いなど

2022/03/13に公開1

OpenID とはなにか

OpenID は認証に関する規約・フォーマットで、OpenID 財団が管理しています。

現在最新のOpenId規約は、OpenID Connect 1.0 (OIDC) と呼ばれるもので、
単に OpenID Connect を指して OpenID と呼ばれるケースも有るようです。

技術的な構成

OpenID Connect (OICD) は、認証に関する仕組みですが、
技術的には単純に ID Token を発行する仕組み、と位置づけることができます。

OICDは、 IDaaS のような サードパーティによる分権的な認証システムの実現を可能にしていますが、
サードパーティーとの接続フォーマットは Oauth2 の方式を踏襲しており、
OICD の技術的な特異点は接続後の ID Token 発行にフォーカスすることができます。

簡略的には以下のような図式が成り立ちます。

Oauth + ID Token = OpenID Connect (OICD)

Oauth2 との役割の違い

一般的に Oauth2 は 認可、OICD は認証の仕組みという形で区別されます。

Oauth2 は、サードパーティからの権限移譲で、
Scope という概念を用いた権限の認可システムを構築するものです。

もちろん Oauth2 も認可の過程で認証の仕組みを用意していますが、
その実態はアクセストークンと言う形でサービス提供者によって比較的バラバラの運用が取られてました。
ここに、OICD は ID Token という形でトークンのフォーマットや利用形態を定義した、というわけです。

Oauth2 は 認可、OICD は認証の仕組みといわれるのは、
技術的関心の中心がどこにあるか、を示したものに過ぎません。

Oauth2 を用いたシステムにも、(アクセストークンベースの)認証の仕組みはもちろんありますし、
OICD を用いるシステムでも、認可のシステムを実現することはもちろん可能です。

OICD の技術的な構成

前述の通り、OICD は ID Token を発行するための仕組みとして位置づけることができます。

ID Token は JWT の一種で、 ID Token を理解するには、まず JWT を理解する必要があります。

https://zenn.dev/mikakane/articles/tutorial_for_jwt

OIDC は Oauth2.0 に 認証の仕組みを導入するにあたって、主に以下のような規約を定義しています。

  1. Oauth2.0 の Authorization Request 送信後の トークンのやり取り
  2. ユーザ認証情報を表現する上での トークンの規約

この 1.2. 周りを総称して、この文章中では、「ID Token を発行するための仕組み」という形で呼んでいます。

OIDC で定義される認証フロー

OIDC では、Oauth2.0 の Authorization Request 送信後の トークンのやり取りを大きく 3つのパターンで定めています。

  • Authorization Code Flow
  • Implicit Flow
  • Hybrid Flow

OIDC を利用した認証フローがどの方式を利用しているかは、Oauth2.0 の Authorization Request における
response_type 値を確認することで判断できます。

  • response_type の 値が code -> Authorization Code Flow
  • response_type の 値が code を含まず id_token を含む -> Implicit Flow
  • その他 -> Hybrid Flow

http://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html#Authentication

どのフローで認証を行ったとしても、最終的には ID Token と Access Token がクライアントに返却されます。

OIDC 利用される ID Token の規約

ID Token は、OIDC で定義されるユーザの認証に関するトークンです。
ID Token は、OIDC で定められた それぞれの認証フローの中でクライアントに対して返却されます。

ID Token は JWT のフォーマットで表現されるトークンです。

JWT では、シンプルにトークンの形式のみが規程されており、
payload 部分のフォーマットやトークン自身の使われ方についてはほとんど言及されていませんでした。

OIDC で規程される ID Token は、JWT の payload 部に一定のフォーマットを提供するものです。
また、ID Token を利用した認証フローの流れなどトークンの利用方法についても細かい規定を追加しています。

OIDC で定める、 JWT の payload 部は以下のような構造を持っています。

interface ID_Token {
    iss: url;           // Issuer Identifier
    sub: string;        // Subject Identifier
    aud: string[];      // Audience
    exp: number;        // Expiration date [UNIXtime]
    iat: number;        // Issued at [UNIXtime]
    auth_time?: number; // End-User authentication time [UNIXtime]
    nonce?: string;
    acr?: string;       // Authentication Context Class Reference
    amr?: string[];     // Authentication Methods References
    azp?: string;       // authorized party
    at_hash?: string;
    c_hash?: string;
    sub_jwk?: object;
    anything_you_want?: any;
}

JWT で定義される一部の 登録済みクレーム が必須の情報として定義されている他、
auth_time や nouce などのセキュリティ上で必要とされる項目が Optional で追加されています。

これらのクレームの役割については、OIDC の 2. ID Token のセクションでそれぞれ定義されています。

http://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html#IDToken

アクセストークンと ID Token の違い

アクセストークンは、認可に関する情報を持つトークンで、
Resource Server に提示する事によって、各種アクションの許可を得るものです。
クライアントは、アクセストークンを利用して、サーバへ要求を発行することができるため、
いわゆる許可証として利用することができます。

クライアントは、許可証を持ってサーバへ要求を発行することができますが、
例えば自信の許可証が書き換えられていることに対して気づくことができません。
許可証が正当なものでも、別の許可を伴うトークンに書き換えられていた場合、
クライアントは、知らない間に意図しない要求をサーバに投げてしまうかもしれません。

一方で、ID Token は、認証に関する情報を持つトークンです。
ID Token は、認証サーバによって発行された、自分自身が誰かを示す、
いわゆる身分証のような存在です。

ID Token の内容は解読が可能であり、また改ざんも困難であるため、
記載されいてる身分情報が正当なものであることを、クライアント自信が検証できるのが特徴です。

sub クレームの中身を見ることで、ユーザの一意性を確認できる他、
aud クレームを確認して、トークンがどのクライアントに向けて発行されたものかを確認することができます。

このように、ID Token はクライアントがそのトークンの正当性を自身で検証できるというのが最大の特徴です。
一般的にアクセストークンはサーバに提示するものとして、クライアント自信が単独でその内容を検証できない構成になっていることがほとんどでしょう。

参考

https://ja.wikipedia.org/wiki/OpenID

https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06

https://baasinfo.net/?p=4418

https://www.buildinsider.net/enterprise/openid/connect

http://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html

Discussion

ritouritou

どのフローで認証を行ったとしても、最終的には ID Token と Access Token がクライアントに返却されます。

これは、IDTokenのみが返されるケースもあるのでそうは言えませんね。以下、参考記事です。
https://zenn.dev/ritou/articles/2796b1cc8b6d32