こんにちは! 株式会社iimonでエンジニアをしている遠藤です。
今まで「OAuth2.0は“認可”のためのプロトコル」と理解していたつもりでしたが、ソーシャルログインなど“認証”の文脈で登場すると、「あれ?認証もできるの?」とモヤモヤすることがよくありました。 これは、OAuth2.0の設計思想と、OAuth2.0をベースにした認証プロトコルの存在をきちんと理解していなかったからだと気づきました・・・。
ということで本記事では、オープン・スタンダードであるOpenID Connectについて、OAuth2.0と比較しながら整理します。
今回はそれぞれの役割や概念を整理し、OpenID Connectがどのような目的でOAuth2.0を拡張したものなのかを理解することに重点を置くため、それぞれの詳細な仕様についてはあまり触れません。
1. 認証と認可の違い
まずは混同しやすい「認証」と「認可」の違いを整理しておきます。
認証(Authentication)
「この人は誰か?」を確認するプロセス。ユーザーが本人であることを証明します。
例:ログイン時のIDとパスワード確認、生体認証など。
認可(Authorization)
「この人に何が許されているか?」を決めるプロセス。認証された主体が、どの操作やリソースにアクセスできるかを制御します。
例:あるユーザーが特定のファイルを読み取り可能かどうか。
この2つの区別は、OAuth2.0とOpenID Connectの違いを理解する上で非常に重要です。
2. OAuth2.0とは
OAuth2.0は、ユーザーのリソースへのアクセス権を安全に第三者に委譲するための「認可」プロトコルです。
主に、クライアントが保護されたリソースへアクセスするために必要なアクセストークンの取得と使用に関する手順が定義されています。
OAuth2.0の登場により、ユーザーは自分のIDやパスワードをクライアントに直接渡さずに、外部サービスにアクセス権を安全に委譲できるようになりました。さらに、どの範囲のアクセスを許可するかのスコープをリソース提供者が定めたアクセス制限に従って、クライアントが選択することができます。
主な構成要素
役割 | 概要 |
---|---|
Resource Owner(リソース所有者) | 通常はユーザー。自身の保護対象リソースへのアクセス権を持ち、第三者に委譲できる立場。 |
Client(クライアント) | リソース所有者に代わって、保護対象リソースへアクセスするアプリやサービス。 |
Authorization Server(認可サーバー) | リソース所有者の認証を行ったうえで、クライアントにアクセストークンを発行する。 |
Protected Resource(保護対象リソース) | リソース所有者がアクセス権を持っているリソースで通常はWeb API。アクセストークンが正当かを確認してアクセスを制御する。 |
標準的なフロー
OAuth2.0には複数の認可フロー(Authorization Grant Type)がありますが、代表的な「認可コードフロー」を簡略化して説明すると、以下のような流れになります。
(※ 以下のフローは認可コードフローを簡略化したものです。認可グラントに関する詳細な処理は省略しています)
1. クライアントは、リソース所有者の代わりに認可を得るため、認可サーバーにリクエストを送る
2. 認可サーバーは、リソース所有者に認証を要求し、ユーザーはクライアントに対してアクセス権の委譲に同意する
3. 認可サーバーは、クライアントにアクセストークンを発行する
4. クライアントはアクセストークンを使用して保護対象リソースへアクセスする
5. リソースサーバーがトークンを検証し、リソースを提供する
OAuth2.0におけるアクセストークンの概要
- 発行元:認可サーバーによって発行されます。
- 目的:クライアントが保護対象リソースへアクセスするための「アクセス権」を示すために使用されます。
- 形式:OAuth2.0の仕様では構造が定義されておらず、実装依存です(例:JWTなど)。
- 可視性:通常、トークンの内容はクライアントからは非公開であり、リソースサーバーが検証します。
ユースケース例
- 外部の写真編集アプリが、ユーザーのオンラインストレージ内の画像にアクセスする
- 家計簿アプリが、銀行の明細データにアクセスする
3. OAuth2.0はなぜ認証プロトコルではないのか
OAuth2.0のフローでは、実装によっては認可サーバーがユーザー認証やクライアント認証を行うため、一見「認証プロトコル」のように見えることもあります。
しかし、OAuth2.0はあくまで認可プロトコルであり、ユーザー認証を目的としたものではありません。その違いは、認可サーバーによって発行されるアクセストークンの性質を見ると、より明確になります。
以下の2点に着目して説明します。
① アクセストークンは「ユーザーの情報」ではなく「アクセス権」を示すもの
アクセストークンの目的は、保護対象リソースに対して「アクセスが許可されたか」を示すことであり、クライアントに対して「ユーザーが誰か」を示すことではありません。
また、アクセストークンのフォーマットや構造はOAuth2.0の仕様で定義されておらず、実装ごとに異なります。そのため、そもそもアクセストークンに「ユーザー情報」が含まれるかどうかは、実装に依存します。そして、ユーザー情報が含まれていたとしても、OAuth2.0の仕様ではクライアントがその内容を解釈・信頼することは想定されていません。
② アクセストークンは「本人確認」の手段にはならない
クライアントがアクセストークンを保持していても、そのトークンが今現在のユーザー本人によるものかを確認する手段はありません。
例えば、リフレッシュトークンを用いれば、ユーザーがその場にいなくてもアクセストークンを再取得できます。つまり、トークンの存在だけではユーザーの「現在のログイン状態」や「本人性」は保証されません。
このように、OAuth2.0では、認証に必要な「誰が・いつ・どこでアクセスしたか」の信頼できる証拠がトークン内に含まれないため、本人確認の手段としては不十分です。
このように、アクセストークンの性質を見れば、OAuth2.0が「認証プロトコル」ではなく、「認可プロトコル」であることがよく分かります。
OAuth2.0は、あえて「権限の委譲が行われたことを安全に伝える」という最小限の責務に限定することで、さまざまなユースケースに対応できる柔軟なプロトコルとして設計されています。
4. OpenID Connect(OIDC)とは
OpenID Connect(OIDC)は、OAuth2.0を土台に「ユーザーが誰か」を安全にクライアントに伝えるための認証プロトコルです。
このプロトコルは相互運用性を重視しており、クライアントは複数のOpenID Provider (OP, IdP)に対して個別の認証ロジックを実装する必要はなく、共通の仕様に従ってログイン機能を構築できます。
OIDCの構成要素(OAuth2.0との対応)
役割 | 説明 |
---|---|
Relying Party (RP) | OpenID Connect を利用する OAuth 2.0 クライアント(ログイン機能を利用するWebサービスやアプリなど) |
OpenID Provider (OP) | OpenID Connect をサポートする認可サーバー(ユーザー認証とトークン発行を行う) |
エンドユーザー | サービスを利用し、認証を受ける本人 |
OIDCによって追加される主要要素
OIDCはOAuth 2.0の認可フローに以下の要素を追加し、ユーザー認証と属性情報の取得を実現します。
IDトークン(ID Token)
IDトークンは、ユーザーが正常に認証されたことをRelying Partyに伝えるためのトークンです。
以下のような特徴があります。
- JWT形式で発行される
- ユーザー認証に関する情報を含む
- クライアント側で検証される
- アクセストークンよりも有効期限が短く設定されることが一般的
- 改ざんを防ぐために、OPの秘密鍵で署名されており、クライアントは公開鍵を使って正当性を検証する
以下のクレームは必須です。
クレーム名 | 説明 |
---|---|
sub |
ユーザーを一意に識別するID(Subject) |
iss |
トークンの発行者(Issuer) |
aud |
トークンの対象(Audience、通常はクライアントID) |
exp |
トークンの有効期限(Expiration) |
iat |
トークンの発行時刻(Issued At) |
UserInfoエンドポイント
IDトークンが「ログイン時点の認証結果」を表すのに対し、UserInfoエンドポイントは、アクセストークンを使って「ユーザーの属性情報」(例:ユーザー名、emailなど)を取得するためのAPIです。
アクセストークンを使って、GETまたはPOSTメソッドでアクセスします。
OpenID Provider(OP)は、受け取ったアクセストークンをもとに、「どのユーザーの情報か」を判断し、対応するユーザー情報を返します。
レスポンスは、ユーザー属性を含むJSON形式のオブジェクトです。
アクセストークンが発行される際にリクエストされたスコープに基づき、返されるユーザー情報の内容は異なります。
標準的なOIDCのフロー
OIDCの基本的な認証フローは以下のように進みます
1. RPがOPに認証リクエストを送信
2. OPがエンドユーザーを認証し、ユーザーがRPにアクセスを許可
3. OPがRPにIDトークンとアクセストークンを返却
4. RPがアクセストークンを使ってUserInfoエンドポイントにアクセス
5. OPがユーザーの属性情報をRPに返却
ユースケース例
補足
今回はオープン・スタンダードであるという理由からOpenID ConnectとOAuth 2.0の比較を行いましたが、すべてのソーシャルログインがOpenID Connectを採用しているわけではありません。
たとえば、GitHubアカウントによるソーシャルログインはOAuth 2.0のみを使用しており、アクセストークンを使ってGitHubのAPI(リソースサーバー)からユーザー情報を取得します。
このときのユーザーの「認証状態」は、OAuth 2.0のフローによって得られたユーザー情報(例:ユーザーIDやメールアドレスなど)をもとに、クライアントが独自に判断しています。
どちらにしても、OAuth 2.0は「アクセストークンの取得と使用」を扱う認可の仕組みであり、それ単体では「認証機能」を提供していないことに注意が必要です。
まとめ
OAuth2.0は本質的に「認可」のためのプロトコルであり、ユーザーの「認証」を担う設計にはなっていません。そのため、認証用途で安全に使うには、OpenID Connectのような拡張仕様が必要になります。OIDCは、OAuth2.0の柔軟性を活かしつつ、標準的な認証の仕組みを提供することで、ログイン処理の安全性と相互運用性を高めています。
今後は、OAuth2.0を土台にした他の拡張仕様についても理解を深めていけたらと思います。
最後までお読みいただき、ありがとうございました!
記事の内容に誤りなどありましたら、ご指摘いただけますと幸いです。
また、弊社ではエンジニアを募集しております。
ぜひカジュアル面談でお話ししましょう!
ご興味ありましたら、ご応募ください!
Wantedly / Green
参考資料
Justin Richer,Antonio Sanso著須田 智之翻訳Authlete, Inc.監修(2019)『OAuth徹底入門 セキュアな認可システムを適用するための原則と実践』翔泳社