【初心者向け】OpenID Connect (OIDC) を学ぶための完全ガイド


【初心者向け】OpenID Connect (OIDC) を学ぶための完全ガイド

はじめに:なぜ今、OpenID Connectを学ぶべきなのか?

「Googleでログイン」「Facebookで続ける」「Apple IDでサインアップ」…。
現代のWebサービスやスマートフォンアプリでは、このような「ソーシャルログイン」機能を目にしない日はないでしょう。ユーザーにとっては、サービスごとに新しいIDとパスワードを覚える手間が省け、非常に便利です。そして、この便利な機能の裏側で、認証の世界標準として活躍している技術こそが OpenID Connect (OIDC) なのです。

Web開発者、インフラエンジニア、あるいはセキュリティに関心のある方なら、OIDCという言葉を一度は耳にしたことがあるかもしれません。しかし、「OAuth 2.0と何が違うの?」「IDトークンって何?」「なんだか複雑で難しそう…」と感じている方も多いのではないでしょうか。

この記事は、まさにそのような方々のために書かれました。OIDCは、現代のセキュアなWebアプリケーションを構築する上で、避けては通れない必須知識となっています。自社サービスにログイン機能を実装する際、ID管理を外部の専門サービス(IDaaS)に任せる際、あるいはマイクロサービス間の認証連携を考える際など、OIDCの知識は強力な武器となります。

このガイドでは、以下の内容を目標に、OIDCの世界をゼロから徹底的に解説します。

  • 認証と認可の違いという基本中の基本から理解できる。
  • OIDCの土台である OAuth 2.0 の役割を明確に把握できる。
  • OIDCの登場人物や専門用語を、具体的な例えを交えて理解できる。
  • 最も重要な「認可コードフロー」の流れを、ステップバイステップで追体験できる。
  • なぜOIDCがセキュアなのか、そのセキュリティの仕組みを説明できるようになる。

この記事を読み終える頃には、あなたは「OIDCって、要するにこういうことでしょ?」と、自信を持ってその仕組みを語れるようになっているはずです。それでは、複雑に見えるOIDCの世界を、一緒に解き明かしていきましょう。


第1章:OIDCを理解するための前提知識

OIDCの核心に迫る前に、まずはその土台となるいくつかの重要な概念を理解しておく必要があります。ここをしっかり押さえることで、後続の章の理解度が格段に上がります。

1. 認証 (Authentication) と 認可 (Authorization) の違い

この二つの言葉は、セキュリティの文脈で頻繁に登場しますが、しばしば混同されがちです。しかし、OIDCを理解する上で、この違いを明確に区別することは絶対不可欠です。

空港での手続きを例に考えてみましょう。

  • 認証 (Authentication):「あなたは誰ですか?」を確認するプロセス

    • 空港のチェックインカウンターで、あなたはパスポートを提示します。係員は、パスポートの写真とあなたの顔を見比べ、「あなたがパスポートに記載された本人である」ことを確認します。これが認証です。
    • Webサービスにおける認証は、「ユーザーが本人であること」を確認する行為です。一般的には、IDとパスワードの組み合わせ、指紋認証、顔認証などがこれにあたります。認証が成功すると、「このアクセスは、確かにユーザーAさんからのものだ」とシステムが認識します。
  • 認可 (Authorization):「あなたは何をしても良いですか?」を決定するプロセス

    • 次に、あなたは搭乗ゲートに向かいます。ここで提示するのは搭乗券です。係員は搭乗券を見て、「あなたがこの便に搭乗する権利を持っている」ことを確認し、ゲートを通ることを許可します。これが認可です。
    • パスポート(本人証明)だけでは、どの飛行機にでも乗れるわけではありません。適切な搭乗券(権利証明)が必要です。
    • Webサービスにおける認可は、「認証されたユーザーが、特定のリソース(データや機能)にアクセスする権限を持っているか」を確認する行為です。例えば、「ユーザーAさんは、自分のプロフィールは編集できるが、他人のプロフィールは閲覧しかできない」といった権限管理がこれにあたります。

まとめると、「認証は本人確認、認可は権限確認」です。この区別を常に意識してください。OIDCはこの「認証」に特化したプロトコルですが、その土台であるOAuth 2.0は「認可」のためのプロトコルです。この関係性が、OIDCを理解する鍵となります。

2. IDaaS (Identity as a Service) とは?

昔は、Webサービスを開発する際、ログイン機能(ユーザー登録、パスワード管理、パスワードリセットなど)を自前で実装するのが当たり前でした。しかし、この実装は想像以上に大変です。

  • パスワードの安全なハッシュ化
  • 総当たり攻撃や辞書攻撃への対策
  • 多要素認証 (MFA) の実装
  • 個人情報保護法など、法規制への準拠

これらのセキュリティ要件をすべて満たす認証基盤を自前で構築・運用するのは、多大なコストと専門知識を要します。

そこで登場したのが IDaaS (Identity as a Service) です。IDaaSは、これらの複雑な認証・ID管理機能を、クラウドサービスとして提供します。代表的なIDaaSには、Okta, Auth0 (Oktaに買収), Microsoft Entra ID (旧Azure AD), Google Cloud Identity などがあります。

開発者は、IDaaSが提供するAPIやSDKを利用することで、自社のアプリケーションにセキュアで高機能な認証システムを簡単に組み込むことができます。そして、これらのIDaaSが外部のアプリケーションとの連携に用いる標準プロトコルこそが、OIDCやOAuth 2.0なのです。

IDaaSは、いわば「認証のプロフェッショナル集団」です。面倒でリスクの高い認証処理はプロに任せ、開発者は本来のサービス開発に集中する。この考え方が、現代のアプリケーション開発の主流になりつつあります。

3. OAuth 2.0 の基本

OIDCは、OAuth 2.0というプロトコルを拡張して作られています。したがって、OIDCを理解するためには、まず親であるOAuth 2.0が何者なのかを知る必要があります。

OAuth 2.0は、「認可」のためのプロトコルです。先ほどの例で言えば、「権限確認」の部分を担当します。OAuth 2.0が解決するのは、「あるサービスが、ユーザーの許可を得て、別のサービスにあるユーザーのデータにアクセスする」というシナリオです。これを「委任認可 (Delegated Authorization)」と呼びます。

少し具体的な例で考えてみましょう。
あなたが「Awesome Photo Editor」という写真編集Webサービスを見つけたとします。このサービスは、あなたのGoogleフォトに保存されている写真を直接編集できる機能が売りです。

もしOAuth 2.0がなければ、どうなるでしょうか?
「Awesome Photo Editor」に、あなたのGoogleアカウントのIDとパスワードを教える必要があります。これは非常に危険です。悪意のあるサービスだった場合、あなたのメールやカレンダーなど、写真以外のすべてのデータにアクセスされてしまう可能性があります。

そこでOAuth 2.0の出番です。OAuth 2.0を使うと、次のような安全な連携が実現できます。

  1. あなたが「Awesome Photo Editor」で「Googleフォトと連携する」ボタンをクリックします。
  2. あなたはGoogleのログイン画面に飛ばされます。(パスワードはGoogleにしか入力しません)
  3. Googleの画面で、「Awesome Photo EditorがあなたのGoogleフォトの閲覧と編集を許可を求めています。許可しますか?」という同意画面が表示されます。
  4. あなたが「許可」すると、Googleは「Awesome Photo Editor」に対して、アクセストークンという特別な「合言葉」を発行します。
  5. 「Awesome Photo Editor」は、このアクセストークンを使ってGoogleフォトにアクセスします。Googleはトークンを検証し、許可された範囲(写真の閲覧と編集のみ)でアクセスを許可します。

この流れのポイントは、ユーザーのパスワードを第三者サービスに渡すことなく、限定的な権限(今回はGoogleフォトへのアクセス権)だけを安全に委任できる点です。

■ OAuth 2.0の登場人物

このシナリオを、OAuth 2.0の専門用語で整理してみましょう。

  • リソースオーナー (Resource Owner): あなた(ユーザー)です。リソース(Googleフォト)の所有者です。
  • クライアント (Client): Awesome Photo Editor。リソースにアクセスしたいアプリケーションです。
  • 認可サーバー (Authorization Server): Googleの認証・認可を担当するサーバー。ユーザーを認証し、同意を得た上で、クライアントにアクセストークンを発行します。
  • リソースサーバー (Resource Server): Googleフォトのデータを保管しているサーバー。アクセストークンを検証し、リソースへのアクセスを許可します。

■ アクセストークン (Access Token)

OAuth 2.0の心臓部とも言えるのがアクセストークンです。これは、クライアントがリソースサーバーにアクセスするための「一時的な鍵」や「許可証」のようなものです。

  • 有効期限が設定されている。
  • 特定のクライアント、特定のユーザー、特定の権限(スコープ)に紐づいている。
  • たとえ漏洩しても、パスワードが漏れるより被害は限定的。

OAuth 2.0は、このアクセストークンを安全に発行し、利用するための「手続き」を定めたプロトコルなのです。

しかし、OAuth 2.0には一つだけ、解決していない問題がありました。それは「認証」です。
Awesome Photo Editorは、アクセストークンを使ってGoogleフォトにアクセスできましたが、「今操作しているユーザーが誰なのか」という情報(ユーザーID、名前、メールアドレスなど)を、標準的な方法で知る術がありません。
この「認証」という最後のピースを埋めるために登場したのが、OpenID Connectなのです。


第2章:OpenID Connect (OIDC) の核心に迫る

前提知識が整ったところで、いよいよ本日の主役、OIDCの登場です。

1. OIDCとは何か? – OAuth 2.0との関係性

OpenID Connect (OIDC) は、OAuth 2.0プロトコルの上に構築された、シンプルなIDレイヤーです。

この一文がすべてを物語っています。
先ほど、OAuth 2.0は「認可」のプロトコルだと説明しました。OIDCは、この「認可」の仕組みをベースに、「認証」の機能を追加したものです。

  • OAuth 2.0: 「Aさんが、アプリBに、サービスCにある自分のデータへのアクセス権限を与える」
  • OIDC: 「アプリBが、サービスCを使って、Aさん本人であることを確認し、Aさんの身元情報(ID、名前など)を取得する」

つまり、OIDCはOAuth 2.0のフローをそのまま利用し、その過程でIDトークンという特別なトークンを追加で発行することで、認証を実現します。この関係性を図で表すと、OIDCがOAuth 2.0を包含しているイメージになります。

[OIDCとOAuth 2.0の関係性のイメージ]

+---------------------------------------------------+
| OpenID Connect (OIDC) |
| |
| [認証機能] |
| - IDトークン |
| - UserInfoエンドポイント |
| |
| +-----------------------------------------------+
| | OAuth 2.0 |
| | |
| | [認可機能] |
| | - アクセストークン |
| | - 認可フロー |
| +-----------------------------------------------+
| |
+---------------------------------------------------+

2. OIDCの登場人物

OIDCの登場人物は、OAuth 2.0とほぼ同じですが、呼び方が少し変わります。

  • End-User (エンドユーザー): OAuth 2.0の「リソースオーナー」と同じく、あなた(ユーザー)です。
  • Relying Party (RP / ライイングパーティ): OAuth 2.0の「クライアント」に相当します。ログイン機能を実装したいWebサービスやアプリのことです。なぜ「Relying Party(信頼する側)」と呼ぶかというと、認証処理をOPに「依存(Relying on)」し、その結果を「信頼する」からです。
  • OpenID Provider (OP / オープンIDプロバイダー): OAuth 2.0の「認可サーバー」と「リソースサーバーの一部」を合わせたような存在です。ユーザーを認証し、RPに対してIDトークンやアクセストークンを発行します。Google, Microsoft, Okta, Auth0などがOPにあたります。

3. OIDCのキーアイテム:IDトークン

OIDCをOIDCたらしめている最も重要な要素が IDトークン (ID Token) です。
IDトークンは、「認証されたユーザーに関する情報」を含んだ、JSON Web Token (JWT) 形式のデータです。

RPは、このIDトークンを受け取り、その内容を検証することで、「確かにこのユーザーはOPによって正しく認証された」と判断し、ユーザーをログインさせることができます。

■ IDトークンの中身(クレーム)

IDトークンはJSON形式のテキストデータで、その中に含まれる個々の情報を クレーム (Claim) と呼びます。代表的な標準クレームには以下のようなものがあります。

  • iss (Issuer): このIDトークンを発行したOPの識別子(例: https://accounts.google.com)。
  • sub (Subject): 認証されたエンドユーザーの一意な識別子。OP内でユニークなIDです。
  • aud (Audience): このIDトークンを受け取るべきRPのクライアントID。自分のサービス宛てのものか確認するために使います。
  • exp (Expiration Time): このIDトークンの有効期限(Unixタイムスタンプ)。
  • iat (Issued At): このIDトークンが発行された日時(Unixタイムスタンプ)。

これらは、IDトークンが「いつ、どこで、誰のために、誰について」発行されたかを示す、セキュリティ上非常に重要な情報です。

さらに、ユーザーのプロフィール情報に関するクレームも含まれることがあります。

  • name: ユーザーのフルネーム。
  • email: ユーザーのメールアドレス。
  • picture: ユーザーのプロフィール画像のURL。

これらの情報を取得するために、後述する scope というパラメータが使われます。

■ なぜIDトークンが必要なのか?

「アクセストークンでユーザー情報を取得すれば良いのでは?」と思うかもしれません。しかし、アクセストークンはリソースサーバーに対する「鍵」であり、その中身はRP(クライアント)が直接解釈すべきものではありません。
IDトークンは、RPが直接読んで「認証イベントの結果」として利用するために設計された、専用のトークンなのです。

4. OIDCの主要なフロー(認可コードフロー)を徹底解説

それでは、OIDCの最も標準的でセキュアなフローである 認可コードフロー (Authorization Code Flow) が、実際にどのように動作するのかを、ステップバイステップで見ていきましょう。

シナリオ: あなたが、ブログサービス「My Awesome Blog」に、Googleアカウントを使って新規登録・ログインしようとしています。

  • End-User: あなた
  • RP: My Awesome Blog
  • OP: Google

【ステップ1】 ログイン開始(ユーザー → RP)
あなたが「My Awesome Blog」のサイトで「Googleでログイン」ボタンをクリックします。

【ステップ2】 OPへリダイレクト(RP → ブラウザ → OP)
RP (My Awesome Blog)は、あなたをOP (Google)の 認可エンドポイント と呼ばれるURLにリダイレクトさせます。このとき、URLには重要な情報(クエリパラメータ)がたくさん付与されています。

https://accounts.google.com/o/oauth2/v2/auth?
response_type=code (→認可コードをください、という指定)
&client_id=xxxx.apps.googleusercontent.com (→私のクライアントIDはこれです)
&redirect_uri=https://my-awesome-blog.com/callback (→処理が終わったらここに戻してください)
&scope=openid%20profile%20email (→openidは必須。加えてプロフィールとメール情報も欲しいです)
&state=af0ifjsldkj (→後で使うランダムな文字列)
&nonce=n-0S6_WzA2Mj (→後で使う一度きりのランダムな文字列)

  • scope: 欲しい情報の範囲を指定します。openid はOIDCのフローを開始するために必須です。profileemail を追加すると、対応するクレーム(名前やメールアドレス)がIDトークンに含まれるようになります。
  • state: CSRF(クロスサイトリクエストフォージェリ)攻撃を防ぐためのランダムな文字列。RPが生成し、後のステップで検証します。
  • nonce: リプレイアタックを防ぐためのランダムな文字列。「number used once」の略で、IDトークンが意図しないリクエストで再利用されるのを防ぎます。

【ステップ3】 ユーザーの認証と同意(ユーザー ⇔ OP)
あなたのブラウザはGoogleの認可エンドポイントに遷移します。
1. あなたはGoogleのログイン画面で、IDとパスワードを入力して認証を行います。(すでにログイン済みの場合はスキップされます)
2. Googleは「My Awesome Blogが、あなたの名前、メールアドレス、プロフィール写真へのアクセスを求めています。許可しますか?」という同意画面を表示します。
3. あなたが「許可」ボタンをクリックします。

【ステップ4】 認可コードを持ってRPへリダイレクト(OP → ブラウザ → RP)
Googleは、ステップ2で指定された redirect_uri (https://my-awesome-blog.com/callback) にあなたをリダイレクトさせます。このとき、URLには 認可コード (Authorization Code) と、先ほどの state 値が付与されています。

https://my-awesome-blog.com/callback?
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7 (→これが認可コード)
&state=af0ifjsldkj (→ステップ2で送ったものがそのまま返ってくる)

【ステップ5】 トークンリクエスト(RP → OP)
あなたのブラウザは関係ないところで、RP (My Awesome Blog)のサーバーが、OP (Google)の トークンエンドポイント に直接リクエストを送ります。この通信はユーザーには見えません。

RPは、受け取った認可コードを使って、IDトークンとアクセストークンを要求します。

リクエスト内容:
* grant_type=authorization_code
* code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7 (先ほど受け取った認可コード)
* redirect_uri=https://my-awesome-blog.com/callback
* client_id=xxxx.apps.googleusercontent.com
* client_secret=GOCSPX-xxxxxxxx (事前に登録したクライアントシークレット)

【ステップ6】 トークンの発行(OP → RP)
OP (Google)は、認可コード、クライアントID、クライアントシークレットなどを検証し、問題がなければ IDトークンアクセストークン をJSON形式でRPに返却します。

レスポンス内容:
json
{
"access_token": "ya29.a0AfH6...",
"expires_in": 3599,
"scope": "openid https://www.googleapis.com/auth/userinfo.profile ...",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ij..."
}

【ステップ7】 IDトークンの検証(RP)
RP (My Awesome Blog)は、受け取ったIDトークンが正当なものであるかを厳密に検証します。

  • 署名は正しいか?(OPの公開鍵を使って検証)
  • iss は期待通りの発行者か?
  • aud は自分のクライアントIDか?
  • 有効期限 (exp) は切れていないか?
  • nonce はステップ2で送ったものと一致するか?

【ステップ8】 ログイン成功
検証がすべて成功すれば、RPは「このユーザーは正しく認証された」と判断します。
RPはIDトークンからユーザーの sub (一意なID) を取り出し、自サービスのユーザーDBと紐付けます。(新規ユーザーならDBに登録します)
そして、RPはセッションを作成し、あなたを「ログイン済み」の状態にします。これで、あなたは「My Awesome Blog」のサービスを利用できるようになります。

【ステップ9】 (オプション) UserInfoエンドポイントの利用
IDトークンには基本的な情報しか含まれていない場合や、追加の情報(住所や電話番号など)が必要な場合、RPは受け取ったアクセストークンを使って、OPの UserInfoエンドポイント に問い合わせることができます。
UserInfoエンドポイントは、そのアクセストークンに紐づくユーザーの情報を返却してくれます。


以上が、認可コードフローの全体像です。一見複雑に見えますが、各ステップの役割を理解すれば、なぜこのような手順を踏むのかが見えてきます。特に、機密情報であるトークンを、ユーザーのブラウザを介さずにサーバー間で直接やり取りしている点が、セキュリティ上非常に重要です。


第3章:OIDCを支える技術要素

OIDCのフローを理解したところで、その背景にあるいくつかの重要な技術要素を深掘りしてみましょう。

1. JWT (JSON Web Token) の構造

IDトークンの実体であるJWT(「ジョット」と読みます)は、情報をJSONオブジェクトとして安全にやり取りするための仕様です。JWTは、.(ドット)で区切られた3つのパートから構成されています。

xxxxx.yyyyy.zzzzz

  1. ヘッダー (Header): トークンの種類(typ)と、署名に使われているアルゴリズム(alg、例: RS256)などの情報を含みます。
  2. ペイロード (Payload): iss, sub, aud などのクレーム(実際のデータ)を含みます。
  3. 署名 (Signature): ヘッダーとペイロードを、ヘッダーで指定されたアルゴリズムとOPの秘密鍵で署名したものです。

ヘッダーとペイロードは、Base64URLエンコードされているだけで、誰でもデコードして中身を見ることができます。したがって、JWTにパスワードなどの機密情報を含めてはいけません。

JWTの最も重要な役割は署名にあります。署名があるおかげで、RPは以下の2点を確認できます。
* 改ざん検知: 誰かが途中でペイロードの中身を書き換えても、署名が一致しなくなるため、改ざんを検知できる。
* 発行者の証明: OPの公開鍵で署名を検証することで、確かにそのOPが発行したトークンであることを確認できる。

jwt.io というサイトに行くと、実際にJWTをデコードしたり、構造を確認したりできるので、ぜひ試してみてください。

2. 各種エンドポイントの役割

OIDCのフローでは、いくつかの特定のURL(エンドポイント)が登場しました。それぞれの役割を整理しておきましょう。

  • 認可エンドポイント (Authorization Endpoint): ユーザーの認証と同意の取得を行う、フローの出発点。ブラウザ経由でアクセスされる。
  • トークンエンドポイント (Token Endpoint): 認可コードと引き換えに、IDトークンやアクセストークンを発行する場所。RPのサーバーから直接アクセスされる。
  • UserInfoエンドポイント (UserInfo Endpoint): アクセストークンを提示することで、ユーザーの詳細情報を取得できる場所。
  • ディスカバリーエンドポイント (Discovery Endpoint): OIDCの設定情報を公開している場所。通常、.well-known/openid-configuration というパスで公開されています。(例: https://accounts.google.com/.well-known/openid-configuration
    • ここには、認可エンドポイントやトークンエンドポイントのURL、サポートしている署名アルゴリズムなど、OPに関するあらゆる情報がJSON形式で記載されています。RPは、このディスカバリーエンドポイントを参照することで、OPの設定を動的に取得できます。

3. ScopeとClaimの関係

フローの解説で scope パラメータが登場しました。scope は、RPがOPに対して「どの情報へのアクセス権限が欲しいか」を伝えるためのものです。

  • openid: OIDCのフローを開始するために必須。これを指定しないと、ただのOAuth 2.0フローになり、IDトークンは発行されません。
  • profile: ユーザーの基本的なプロフィール情報(name, family_name, gender, pictureなど)へのアクセスを要求します。
  • email: ユーザーのメールアドレス(email, email_verified)へのアクセスを要求します。
  • address: 住所情報へのアクセスを要求します。
  • phone: 電話番号へのアクセスを要求します。

RPがリクエストした scope に応じて、OPは同意画面を表示し、許可が得られれば、対応するクレームをIDトークンやUserInfoレスポンスに含めて返却します。
このように、scope はユーザーのプライバシーを守る上で非常に重要な役割を担っており、RPは必要最小限の scope のみを要求することが推奨されます。


第4章:OIDCのセキュリティを考える

OIDCは、数々のセキュリティ上の脅威を考慮して設計されています。なぜOIDCがセキュアだと言えるのか、その主要な仕組みを見ていきましょう。

1. state パラメータの役割 (CSRF対策)

CSRF (Cross-Site Request Forgery) は、攻撃者がユーザーを騙して、意図しないリクエストをWebサービスに送信させる攻撃です。

もし state パラメータがなければ、次のような攻撃が可能になります。
1. 攻撃者は、自分自身のGoogleアカウントで「My Awesome Blog」の連携を開始し、認可コード発行直前のURL(攻撃者用の認可リクエストURL)を取得します。
2. 攻撃者は、そのURLを罠として、被害者(あなた)にクリックさせます。
3. あなたは、すでにGoogleにログイン済みの場合、無意識のうちに同意処理が進み、攻撃者のアカウントと紐付いた認可コードが、あなたのブラウザ経由で「My Awesome Blog」に送られてしまいます。
4. 結果として、あなたは「My Awesome Blog」に、攻撃者のアカウントでログインさせられてしまうことになります。

state は、この攻撃を防ぎます。
RPは、リダイレクトする際にランダムな state 値を生成し、セッションに保存しておきます。そして、OPから戻ってきた際に、返却された state 値がセッションに保存したものと一致するかを検証します。
攻撃者が作ったURLには正しい state 値が含まれていないため、RPはリクエストを不正なものとして拒否できます。

2. nonce パラメータの役割 (リプレイアタック対策)

リプレイアタックは、一度傍受した正当な通信データを、後で再利用して不正アクセスを試みる攻撃です。

IDトークンは、それ自体が「認証成功」の証明書です。もし攻撃者がなんらかの方法であなたのIDトークンを盗み出した場合、それを使ってあなたになりすましてRPにログインできてしまう可能性があります。

nonce は、これを防ぎます。
RPは、state と同様に、リダイレクト時に一度きりのランダムな nonce 値を生成してセッションに保存します。OPは、発行するIDトークンのペイロード内に、この nonce クレームを含めます。
RPは、IDトークンを検証する際、トークン内の nonce がセッションに保存したものと一致するかを確認します。一度使った nonce は無効化するため、たとえIDトークンが盗まれても、再利用(リプレイ)することができなくなります。

3. PKCE (Proof Key for Code Exchange) とは?

PKCE(「ピクシー」と読みます)は、認可コード横取り攻撃を防ぐための拡張仕様です。

認可コードフローでは、認可コードはブラウザのURL経由でRPに渡されます。このとき、悪意のあるアプリがOSにカスタムURLスキームを登録している場合など、何らかの方法でこの認可コードを横取りされてしまう危険性がありました。(特にスマートフォンアプリで問題になりました)
攻撃者は、横取りした認可コードを使えば、正規のRPになりすましてトークンを取得できてしまいます。

PKCEは、この攻撃を次のように防ぎます。

  1. リクエスト時: RP (クライアント) は、まず code_verifier というランダムな文字列を生成します。次に、それをハッシュ化(SHA256など)して code_challenge という文字列を作ります。認可リクエストの際に、この code_challenge を(ハッシュ化手法と共に)OPに送ります。
  2. トークン要求時: RPは、トークンエンドポイントにリクエストを送る際、ハッシュ化する前の元の文字列である code_verifier を含めます。
  3. 検証: OPは、受け取った code_verifier を同じ方法でハッシュ化し、それが最初に受け取った code_challenge と一致するかを検証します。

もし攻撃者が認可コードを横取りしても、元の code_verifier を知らないため、トークンを要求することができません。
PKCEは、もともとクライアントシークレットを安全に保持できないモバイルアプリやSPA(Single Page Application)向けに考案されましたが、現在ではそのセキュリティ上の利点から、サーバーサイドのWebアプリケーションも含め、すべてのクライアントタイプで利用することが強く推奨されています。

4. IDトークンの厳密な検証

前述の通り、RPは受け取ったIDトークンを必ず検証しなければなりません。ライブラリを使えば自動的に行われることが多いですが、何を確認しているのかを理解しておくことは重要です。

  • 署名の検証: 最も重要。改ざんやなりすましを防ぐ。
  • iss (Issuer) の検証: 意図したOPから発行されたものか。
  • aud (Audience) の検証: 自分宛てのトークンか。
  • exp (Expiration Time) の検証: 有効期限が切れていないか。
  • nonce の検証: リプレイアタックを防ぐ。
  • (iat (Issued At) の検証): 発行時刻が未来になっていないかなど。

これらの検証を怠ると、深刻な脆弱性につながる可能性があります。自前で実装しようとせず、必ず実績のあるOIDCライブラリを利用しましょう。


第5章:実践!OIDCを体験してみよう

理論を学んだら、実際に手を動かして体験してみるのが一番です。ここでは、プログラミングは不要で、Web上のツールだけでOIDCのフローを擬似的に体験する方法を紹介します。

準備するもの:
* Googleアカウント
* OAuth 2.0 / OIDCのデバッグツール(例: https://oidcdebugger.com/

ステップ1:Google Cloud PlatformでクライアントIDとシークレットを発行する

まず、OIDCのRP(クライアント)としてGoogleに登録する必要があります。

  1. Google Cloud Platform (GCP) にアクセスし、新しいプロジェクトを作成します。
  2. ナビゲーションメニューから「APIとサービス」→「認証情報」を選択します。
  3. 「認証情報を作成」→「OAuth クライアント ID」を選択します。
  4. 「アプリケーションの種類」で「ウェブ アプリケーション」を選択します。
  5. 「承認済みのリダイレクト URI」に、使用するデバッグツールのコールバックURLを追加します。今回は https://oidcdebugger.com/debug を追加しましょう。
  6. 「作成」ボタンを押すと、クライアントIDクライアントシークレットが表示されます。これらをメモしておきます。(クライアントシークレットは絶対に他人に教えないでください)

ステップ2:デバッグツールで認可リクエストを組み立てる

  1. oidcdebugger.com にアクセスします。
  2. Authorize URI に、Googleの認可エンドポイントURLを入力します。これはGoogleのディスカバリーエンドポイント (https://accounts.google.com/.well-known/openid-configuration) で確認でき、通常は https://accounts.google.com/o/oauth2/v2/auth です。
  3. Client ID に、ステップ1で取得したクライアントIDを貼り付けます。
  4. Redirect URIhttps://oidcdebugger.com/debug が設定されていることを確認します。
  5. Scopeopenid profile email と入力します。
  6. Response Typecode を選択します。
  7. StateNonce は、ツールが自動でランダムな値を生成してくれます。
  8. 「Send Request」ボタンをクリックします。

ステップ3:同意画面を確認し、認可コードを取得する

ボタンをクリックすると、Googleのログイン画面と同意画面にリダイレクトされます。内容を確認して「許可」すると、oidcdebugger.com に戻ってきます。
画面には、URLに付与された code (認可コード)state が表示されているはずです。

ステップ4:認可コードを使ってトークンをリクエストする

oidcdebugger.com の画面は、自動的にステップ2(トークンリクエスト)に進んでいます。

  1. Token Endpoint に、Googleのトークンエンドポイント (https://oauth2.googleapis.com/token) が設定されています。
  2. Client Secret の欄に、ステップ1で取得したクライアントシークレットを貼り付けます。
  3. 必要な情報は自動で入力されているので、「Exchange Code for Tokens」ボタンをクリックします。

ステップ5:取得したトークンを確認する

成功すると、画面に Access TokenID Token が表示されます。
表示されたIDトークンは、長い文字列(JWT)です。これをコピーして jwt.io のDebuggerに貼り付けてみてください。
ペイロード部分に、iss, sub, aud や、name, email といったクレームが含まれているのが確認できるでしょう。

おめでとうございます!これであなたは、OIDCの認可コードフローの一連の流れを、実際に体験することができました。


まとめ:OIDCをマスターして、セキュアで便利なWebサービスを構築しよう

本ガイドでは、初心者の方を対象に、OpenID Connect (OIDC) の世界を体系的に解説してきました。
最後に、重要なポイントを振り返りましょう。

  • 認証は本人確認、認可は権限確認であり、OIDCは「認証」、その土台であるOAuth 2.0は「認可」を扱います。
  • OIDCは、OAuth 2.0のフローにIDトークン (JWT) を追加することで、標準化された認証の仕組みを提供します。
  • 認可コードフローは、機密情報をサーバー間で安全にやり取りする、最もセキュアで標準的なフローです。
  • state, nonce, PKCE といった仕組みが、CSRF、リプレイアタック、認可コード横取りといった脅威からアプリケーションを守ります。
  • OIDCを実装する際は、自前で組むのではなく、信頼できるライブラリやIDaaSを利用することが極めて重要です。

OIDCは、もはや単なる「ソーシャルログインのための技術」ではありません。それは、サービス間のID連携、マイクロサービスの認証基盤、そしてゼロトラストセキュリティといった、現代的なシステムアーキテクチャの根幹を支える、ID連携の共通言語です。

このガイドが、あなたのOIDC学習の第一歩となり、よりセキュアで、よりユーザーフレンドリーなWebサービスを構築するための一助となれば幸いです。OIDCの世界は奥深く、CIBA(Client Initiated Backchannel Authentication)のような高度なフローも存在します。ぜひ、この知識を足がかりに、さらなる学習を進めてみてください。

認証の世界は複雑ですが、その標準化された道を照らす灯台、それがOpenID Connectなのです。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール