OpenID Connectについて勉強したのでまとめる
はじめに
前回はOAuthについてまとめましたが、今回はOpenID Connectについてまとめてみたいと思います。
間違っているところがあればご指摘ください。
OpenID Connectとは
OpenID Connect は OAuth 2.0 認可プロセスを拡張し, 認証目的で利用できるようにする. 本拡張を利用する場合, Client は openid
scope を指定して Authorization Request を送信する. 認証結果は ID Token (Section 2
参照) と呼ばれる JSON Web Token (JWT)
[JWT] として返される. OpenID Connect をサポートする OAuth 2.0 Authentication Server は, OpenID Provider (OP) とも呼ばれる. OpenID Connect を利用する OAuth 2.0 Client は Relying Party (RP) とも呼ばれる.
(OpenID Connect Core 1.0 incorporating errata set 1より引用)
つまり、OAuthの仕様を拡張し、アクセストークンに加えてIDトークンを発行することで、認証を行うことを可能にするためのものということができるかと思います。
OAuthはあくまで認可のための権限の移譲プロセスを定めた仕様であるため、本来、認証は仕様の範囲外です。しかしOAuthの「ユーザーIDとパスワードの管理を外部に任せられる」「ユーザー登録作業を簡略化できる」という利点から、OAuthによる認証というものが広まりました。
しかしながらOAuth認証は後述する問題点を孕んでいるため、OAuthの利点を享受しながら問題点を解消するための仕組みとして、OpenID Connectという仕様がOAuthの上に乗せる形で策定されたという経緯があります。
OAuthによる認証の問題点
まずOAuth認証とは何かというと、ユーザー情報(emailやuser_idなど)を対象リソースとしたOAuthによる認可プロセスを利用して取得したユーザー情報をもって認証を実行することです。
以下はインプリシットグラントタイプのOAuthのシーケンス図ですが、最後にリソースサーバーから返されるのがユーザー情報であれば、クライアントはこのユーザー情報をもって認証処理を実行することができます。
これの何が問題なのでしょうか。
アクセストークンにはクライアントを確認するための仕組みがありません。つまり誰宛に発行したアクセストークンなのかに関わらず、リソースサーバーはリソースを返してしまうということです。このため、クライアントが悪意あるクライアントであった場合、上記のフローで取得した他人のアクセストークンを使って、OAuth認証を採用している任意のサイトになりすましログインが可能となってしまいます。
OpenID ConnectではIDトークンというものを用いてこの問題に対処しています。次はIDトークンとは何かについてみていきましょう。
IDトークンとは
以下の情報および署名を含むトークン。JWT(JSON Web Tokenの略。詳細の説明は割愛)という形式でIDプロバイダ(OpenID Connectの登場人物の項を3章)から発行される。
IDトークンに含まれる情報(代表的なもののみ掲載。オプショナルな情報がこれら以外に付与されることもある)
- iss
Issuerの略。IDトークンの発行者 - aud
Audienceの略。IDトークンの発行を受けるクライアントIDが入る - sub
Subjectの略。エンドユーザーの識別子。これを持ってエンドユーザーを識別できる - iat
Issued Atの略。JWTの発行時間を表す。 - exp
Expiration timeの略。トークンの有効期限 - nonce
リプレイアタック防止のためのランダムな文字列
IDトークンには、ユーザー識別子、IDトークンの発行元、発行先などの情報が含まれるため、これらの情報が改竄されていないことを確認するために署名が含まれています。
OAuth認証と比べて、IDトークンの仕組みによって、ユーザー識別子、IDトークンの発行元、発行先などの情報が含まれているため、これらを適切に検証することでユーザーのなりすましを防ぐことができます。
OpenID Connectの登場人物
OpenID ConnectはOAuthの拡張仕様ですが、OAuthと登場人物の呼び方が異なります。
以下が対応表となります。
OAuth | OpenID Connect |
---|---|
リソースオーナー | エンドユーザー |
クライアント | リライングパーティ |
認可サーバー | IDプロバイダ |
リソースサーバー | UserInfoエンドポイント |
OpenID Connectのフローの種類
- 認可コードフロー
OAuthの認可コードグラントタイプに対応するフロー。コンフィデンシャルなリライングパーティにおいて適応されるフロー - インプリシットフロー
パブリッククライアント向けのフロー - ハイブリッドフロー
ネイティブアプリにバックエンドサーバーがある場合など、パブリッククライアントとコンフィデンシャルクライアントの両方で構成されるリライングパーティにおいて適応されるフロー
シーケンス図
一番重要な認可コードフローのみ掲載します(以下の参考書籍に掲載されているものをdiagrams.netで写経してみたものになります。OAuthの記事でも書きましたが、この著者の方の本はどれも超勉強になるのでぜひ読んでみてください)
OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本 - Auth屋 - BOOTH
シーケンス図は以下の通りです。
OAuthの認可グラントタイプのシーケンス図とほぼ同じですが、トークンリクエストのレスポンスにIDトークンが含まれており、IDトークンの検証のプロセスが存在するのが大きな違いとなっています。
まとめ
OpenID Connectの仕様は奥が深く、全然表面の部分しか書けていないですが、さらに勉強を進めてまたの機会に深掘りした記事を書いていきたいと思います。
次回はセキュリティ的に重要な仕組みだが混乱しがちな、state, PKCE, nonce, c_hash, at_hashの違いについてまとめていきたいと思います。
参考
OpenID Connect Core 1.0 incorporating errata set 1
OAuth 2.0 + OpenID Connect のフルスクラッチ実装者が知見を語る - Qiita
IDトークンが分かれば OpenID Connect が分かる - Qiita
Discussion