🪪

ID連携を理解しよう(1) ID連携の概要とOAuth, OIDCで実現できること

2025/01/04に公開
2

ritou です。

あけましておめでとうございます。2025年はID連携の話をしましょう。

昨年、仕様策定から10年を迎えたOpenID Connectですが、関連仕様の策定は続いています。特に最近はDigital Identity Walletを支える仕様群の策定がお盛んです。新しい技術をキャッチアップするためにも、ベースとなるID連携の概要から理解していく必要があると考えています。

今回はID連携とは、というところとどうしても混乱してしまうOAuthとOIDCの用途について理解するための説明をします。OAuth/OIDC関係はどうしても記事が長くなってしまうので、今後のモチベーションのためにも「ID連携を理解しよう(1)」としています。

ID連携とは

ID管理などで使われるID(=Identity)とはユーザーの属性情報の集合です。
ユーザー識別子(User Identifier)やメールアドレスも属性情報です。パスワードとの組み合わせでログインに利用するものは「当人認証のためのクレデンシャル」と呼ばれます。
一人の人物(Entity)に対して、サービスやコンテキストにより利用される属性情報の種類も組み合わせも変わります。つまり、我々は複数のIdentityを使い分けているということになります。

ID連携とは、異なるサービス間でユーザー情報のやり取りを行うことです。

これを安全に実現する仕組みが考えられており、その中の一つがOIDC(OpenID Connect)です。

OIDC: ユーザー情報を安全に受け渡す仕組み

OIDCの概要

OpenID Connectで実現できることは、あるサービス、アプリケーションから別のサービス、アプリケーションに対してユーザー情報を提供することです。 先ほどは "やり取り"と説明しましたが、基本的には一方通行の仕組みです。ユーザー情報を提供する側をIdentityProvider、利用する側をRelying Party と呼びます。

どのようにユーザー情報を渡すかというところで、IDTokenというのが定義されています。
IDTokenとはIdPがユーザー情報を提供するイベント自体の情報(誰が、誰に、いつ...)とユーザー情報(ユーザー識別子、メールアドレス、プロフィール情報)を含み、受け取ったRPがそれを検証可能な状態として発行するトークンです。 技術的には、JSON Web Token/JSON Web Signatureといった仕様が使われています。

RPがIdPにユーザー情報を要求したら、IdPがユーザーにログインをさせてRPにユーザー情報を渡すことへの同意を得ます。その結果、IdPから提供されたIDTokenによってRPはユーザー情報を利用できるというのがOIDCの仕草です。

なんだよ状況提供って。typoしてるじゃねーか

少し言葉遊びをしましょう。IDTokenのIDの部分はユーザー識別子であるIdentifierではなく、ユーザー情報自体を示すIdentityでもなく、身分証であるIdentity Documentとするとしっくりくるでしょう。IDToken=Identity Document Token、つまり身分証トークンです。Relying PartyはIDTokenを検証し、それに含まれるユーザー情報を「当人認証」や「身元確認」に利用できます。 詳細は次節で解説します。

IDTokenとは別に、RPが「非同期でIdPからユーザー情報を取得して利用」するためのAccess Token / Refresh Token と言うOAuth 2.0で定義されているトークン もIdPから必要に応じて発行されます。OAuthについては後から説明します。

例えばIdP側のユーザー情報のうち表示名(ニックネーム)をRPで利用しており、IdP側で変更があった場合を考えましょう。
Relying Party側では非同期でユーザー情報を取得できたタイミングでそれを同期できます。

これらのトークンの受け渡し、そしてユーザー情報をトークンに含んだりAPIで返す際のフォーマットを標準化したものがOIDCの仕様です。

https://openid.net/specs/openid-connect-core-1_0.html

OIDCのIDTokenを用いたRPによる「当人認証」と「身元確認」

RPはOIDCを "当人認証"、"身元確認"の両方で利用できます。"当人認証"と"身元確認"については次のようなものです。

  • "当人認証": サービス登録済みのユーザーを識別し、検証する処理
  • "身元確認": ユーザーが主張した属性情報の有効性、ユーザーとの関係を検証する処理

まずは "身元確認" から見ていきます。

いわゆるユーザーの新規登録フローにおいて、次の2つの処理が行われます。

  • "身元確認": メールアドレスやSMS番号などコンタクト先の確認
    • 例: メールにURLや認証コードを送って確認
  • ユーザー作成: ユーザーIDを発行し、内部でデータを作成する
    • 例: ログイン状態となりサービスを利用できるようになる。また、パスワードを設定して以後は確認したメールアドレスとパスワードでログイン可能となる。

RPがOIDCで受け取ったIDTokenにはIdPで確認済みのメールアドレスやSMS番号が含まれ、IdPを信頼する場合はRP自身で行う"身元確認"をスキップして確認済みの属性情報として利用します。

また、IdPがSNSでサービスもプロフィール情報を登録させる場合、IdPがアイコン画像やニックネームをそのまま利用もしくは入力フォームの補完として利用します。RPのサービスとIdPのユーザー情報と親和性が高い場合、サービスの利用開始時のUX向上が期待できます。

「当人認証」について、ユーザー作成の際にRPはまず「IdPの識別子」と「IdPから受け取ったIdPのユーザー識別子」にRPのユーザーを紐付けます。
この後はソーシャルログイン機能として、IdPから受け取った「IdPの識別子」と「IdPのユーザー識別子」に紐づけられたユーザーでログインできるようになります。

このように、OIDCのRPは身元確認と当人認証のための設定を(必要に応じて)1ステップで実現できます。

より詳しく整理したい場合、ガイドラインとして、NIST SP 800-63シリーズが参考になります。

  • SP 800-63A: Enrollment & Identity Proofing(身元確認)
  • SP 800-63B: Authentication(当人認証) & Lifecycle Management
  • SP 800-63C: Federation(ID連携) & Assertions

"ID連携"と"当人認証", "身元確認"が分かれていることに留意しましょう。

https://pages.nist.gov/800-63-3/

OAuth: あるサービスに対して安全にリソースアクセスを提供する仕組み

今回はOAuthについても整理しておきましょう。

OAuthの概要

OIDCに対して、OAuthで実現できることは あるサービスが別のサービスに対し、安全にリソースアクセスを提供する仕組み です。このリソースアクセスとは、リソースを提供するリソースサーバーへのHTTPリクエストを用いたAPIリクエストに限らず、様々なプロトコルへの適用を意識しています。

リソースとリソースオーナーについて、OAuthでは次のようなパターンがあります。

  • ユーザーがリソースオーナー、サービス上のユーザーに紐づくデータがリソース
  • サービス自体がリソースオーナー、サービスに紐づくデータがリソース

OIDCがユーザー情報にフォーカスするのに対してOAuthにおけるリソースアクセスの範囲は広いことに留意しましょう。 自分はID連携に対してデータ連携と表現したりしています。

OAuthで解決したい課題としては、次のような実装からくるものです。

  • リソースオーナーが、リソースアクセスを行うサービス(クライアント)にクレデンシャル(ID/パスワードなど)を預ける
  • クライアントはそのクレデンシャルを用いてリソースアクセスを行う

技術的なところで言うと、Basic認証を用いたリソースアクセスがわかりやすいところでしょう。
ブラウザから利用されるWebページにBasic認証が設定され、アクセス制御が行われることは割と一般的です。その仕組みがAPIアクセスに導入されると、リソースオーナーはクライアントにユーザーIDとパスワードを預けてクライアントがリクエストへその値を指定します。一時的とはいえユーザーのパスワードを預ける仕組みには漏洩や悪用のリスクがあります。

OAuthではその代わりに、アクセストークンと呼ばれるアクセス制限用のトークンを利用します。リソースアクセスを行うサービスがアクセストークンを利用することで、リソースを提供するリソースサーバーは誰(サービス)がどのリソースへ、いつまでのアクセスが許可されているのかなどを確認でき、許可されている場合のみリソースを提供するというアクセス制御が可能です。

ここまでを踏まえて、OAuthの機能として定義されているのは次の2つです。(RFCにて"など"と書いているのは関連仕様がたくさんあるため、これ"だけ"ではないからです。)

  • アクセストークンを利用したリソースアクセス: OAuth 2.0ではRFC6750など
  • アクセストークンの発行、更新: OAuth 2.0ではRFC6749など

OIDCがIDTokenを用いてユーザー情報を提供する部分にフォーカスしているのに対し、OAuthではリソースアクセスに必要なアクセストークンの発行と利用が定義されています。 シンプルな実装で実現できるものから、金融、ヘルスケアといったより高い安全性が求められるユースケースまでをサポートするため、様々な仕様やプロファイルがIETFやOIDFにて定義されています。

メールソフトから見るリソースアクセス技術の変遷

OAuthでは、リソースアクセスを許可する認可サーバーが誰のリソースへのアクセスを許可するのかを判断し、リソースサーバーがそれを確認できるようにするため にリソースオーナーの認証が必要です。ユーザー情報を返すAPIが用意されておりそれを利用した結果、クライアントはリソースオーナーの情報を取得できます。しかし、クライアントは自身のリソースアクセスのためにリソースオーナーが誰なのかを知る必要はありません。 OIDCとの違いはこの辺りにあります。

そして、このような考えがよくわかるユースケースとして、メールソフトにおけるリソースオーナーの"認証"があります。メールソフトは同期または非同期でメールプロバイダとやりとりし、メール操作(=リソースアクセス) を行います。ここでリソースオーナーの認証が必要な理由はなんでしょうか? メール操作のためには対象のメールアカウント(=リソースオーナー)は誰かをメールプロバイダに伝える必要があります。 メールソフトがリソースオーナーを認証してコンテンツを出しわけしたいわけではないのです。

この "メールアカウントの認証" 機能について、いくつかの方式があります。詳細には触れずに、今回は "パスワードを利用するもの" とそうではないものに分けて整理します。そして、ユーザー側の事情としてメールプロバイダがユーザーに指定させるパスワードにもいくつかの種類があります

  1. メールプロバイダのアカウント自体のID/PW を設定
  2. アカウント自体のPWではなく、メールプロバイダがメールソフトでの利用のために個別に払い出した "アプリパスワード" を設定
  3. パスワードを指定しないOAuthの仕組みを利用

メールソフトの設定の際、送受信のためのサーバーの情報と共にメールアドレス、ID、パスワードと言ったアカウント情報を設定するのが長らく一般的でした。そこで設定するアカウント情報について、Googleやヤフーに代表されるような大規模なサービスを展開しているメールプロバイダの場合、ユーザーが普段から利用しているパスワードを設定することになります。いくら自身の端末で動作するソフトウェアとはいえ、そこにパスワードを預ける以上は漏洩、悪用といったリスクはあります。また、メールソフトと同じ感覚でWebメールで外部のメールアカウントを扱うこともできるようになり、そのリスクも広がったと捉えることもできるでしょう。

また、ユーザー認証方式にも変化が起こり、2要素/2段階認証を導入する場合も影響が出ます。2要素/2段階認証を利用しているユーザーに対して、メールソフトからのアクセスはパスワードのみとなるとそこを狙われる可能性が出てきます。逆に、メールソフトからは利用できなくなるのも悩ましいところです。

そこで、GoogleやMicrosoftなど大手のサービスはメールソフト専用のパスワードを払い出すいわゆる "アプリパスワード" というものを払出し、設定させるようにしました。 このアプリパスワードには利用可能なリソースを制限できるものもあり、メールソフト側はこれまで通りで入力するパスワードを変えるだけで上記の漏洩や悪用のリスクを軽減できます。
メールソフト以外だと、CalDAVという仕組みを利用するカレンダーアプリでアプリパスワードの利用ができます。最近だと Bluesky などでもアプリパスワードに言及されることがあったので認識しやすいでしょう。

https://support.google.com/accounts/answer/185833?hl=ja

https://support.microsoft.com/ja-jp/account-billing/アプリ-パスワードを取得して使用する方法-5896ed9b-4263-e681-128a-a6f2979a7944

https://bluesky-jp.github.io/welcome-bluesky/docs/walks/password

そして最近は OAuthの仕組みを利用してパスワードを扱わなくてもメール機能を利用可能になっているものが出てきて、メールプロバイダもそちらの方向に切り替えているところが出てきました。OAuthの仕組みを利用することで、ユーザーは2要素/2段階認証を利用しつつメールソフトの設定が可能となり、メールソフトはメール操作のためだけのトークンを保持することになります。アプリパスワードよりも設定時のUXや安全性を高められる仕組みといえます。

https://support.mozilla.org/ja/kb/thunderbird-and-gmail

2要素/2段階認証が普及した段階、というかOAuthが出てきた時点でそのサポートと切り替えが進むのが好ましかったとは思いますが、当然ながらメールソフトを開発しているサービスはメールプロバイダとは別のところなのでサクサク進む話ではありませんでした。時間をかけてようやくOAuthが当たり前に使われるようになった感じです。この話は別途記事を書いたことがあるので読んでみてください。

https://zenn.dev/ritou/articles/4e104c87959057

まとめ

  • ID連携は異なるサービス(アプリケーション)間でユーザーの属性情報をやりとりする仕組み
  • OIDCは「ユーザー情報をサービス間で安全にやり取りする仕組み」
    • RPは確認済みの属性情報を用いて「身元確認」、IdPから受け取ったユーザー識別子を持って「当人認証」に利用可能
  • OAuthは「あるサービスに対して安全にリソースアクセスを提供する仕組み」
    • ユーザーだけではなくサービス自体がリソースオーナーとなる場合もある
    • クレデンシャルを預ける方法からOAuthへの変遷はメールソフトの歴史を見ると理解しやすい

プロトコルから入ると「プロトコルが目指す目的と、その仕様で実現可能な範囲」を混乱しがちです。(下手に考えて混乱してしまった状態からの理解というところでは、Auth屋さんの本を読んでもらうのが良いかもしれません)

OIDCは認証、OAuthは認可 という表現は 「双方にある程度理解が進んだ段階で、違いを端的に表現しようとしてできていないやつ」 なので、(自戒の意味も込めて)あまり使うのは避けるべきでしょう。

次回はパスキーとの関係について触れましょう。こちらの記事で予習してもらうと秒で理解できると思います。

https://zenn.dev/ritou/articles/f0d190df1f6d96

ではまた!

おまけ

Digital Identity技術勉強会 #iddance Advent Calendar 2024はまだ終わっていない!

https://qiita.com/advent-calendar/2024/iddance

あと2つ!

Discussion

Takahiro TanakaTakahiro Tanaka

仕事でOAuth, OIDCあたりの検討をした経験が少しあるのですが、後半の理解が難しいです...
・クライアント
・ユーザー
・リソースオーナー
の正確な定義とか。もしかして説明箇所によって言葉の意図が変わってるのでしょうか? 次の一文

 “クライアントは自身のリソースアクセスのためにリソースオーナーが誰なのかを知る必要はありません。”
この”自身”とは”クライアント”のこと?あるいは”リソースオーナー”ですか?

うーーーんシーケンス図的なものが無いと理解が難しい。

ritouritou

“クライアントは自身のリソースアクセスのためにリソースオーナーが誰なのかを知る必要はありません。”
この”自身”とは”クライアント”のこと?あるいは”リソースオーナー”ですか?

クライアントです。

OAuthの方は定義のとこまるっと抜けてますね。申し訳ないです。後で追記します。

シーケンスよりまえに概念としておさえてもらいたい話ではあるのですが、まだまだ説明できてない部分が多いですね。指摘された部分は今後の記事に生かしたいと思います。