このシリーズでは、API キーやセッションとトークン、API の認証方式を図にしてきました。その中で何度も出てきたのが「Bearer トークン」と OAuth 2.0 です。「Microsoft でサインイン」のボタンや、「このアプリに次のアクセス許可を与えますか」という画面の裏で動いているのも OAuth 2.0 です。この記事では細かい手順に入る前に、OAuth 2.0 が何を解決するしくみなのか、誰が登場して何を受け渡すのかを、RFC と Microsoft のドキュメントで確かめながら図にしました。
- OAuth 2.0 は、パスワードを渡さずに、アプリに「決まった範囲の操作」だけを任せるしくみ
- 登場人物は4つ:リソースオーナー・クライアント・認可サーバ・リソースサーバ
- アクセストークンは「範囲と期限のある通行証」
- トークンのもらい方(グラント)の種類と、今使われているもの
- OAuth 2.0 は「認可」のしくみで、サインイン(認証)は OpenID Connect が足す
- 動かす前に、アプリと API を認可サーバに登録しておくこと
まずは身近な例で:写真の印刷を頼む
OAuth 2.0 の仕様(RFC 6749)は、こんな例から説明を始めています。写真共有サイトに置いた写真を、別の会社の印刷サービスで印刷したい。印刷サービスは、写真共有サイトから写真を取り出す必要があります。
いちばん簡単なのは、写真共有サイトの ID とパスワードを印刷サービスに教えることです。でも、これにはいろいろな困りごとがあります。
RFC 6749 は、パスワードを渡すやり方の問題として次のようなものを挙げています。右の列が、OAuth 2.0 でどう変わるかです。
| パスワードを渡すと | OAuth 2.0 では |
|---|---|
| 印刷サービスが、あとで使うためにパスワードを保存しておくことになる | 印刷サービスにパスワードは渡らない。渡るのは通行証(トークン)だけ |
| 印刷サービスが、写真以外のものまで広く触れてしまう | 通行証には「写真を読む」のような範囲が付く |
| 印刷サービスだけ使えなくするには、パスワードを変えるしかなく、ほかのサービスも全部止まる | 通行証は、サービスごとに取り消せる |
| 印刷サービスから漏れると、パスワードそのものが漏れる | 漏れるのは範囲と期限のある通行証で、パスワードではない |
つまり OAuth 2.0 は、パスワードの代わりに、範囲と期限のある通行証をアプリに渡すしくみです。RFC 6749 も、クライアントはリソースオーナーの資格情報(パスワードなど)を使う代わりにアクセストークンを手に入れる、と書いています。
登場人物は4つ
OAuth 2.0 では、関係する人やサーバを4つの役割に分けます。写真の例に当てはめると、次のようになります。
| 役割 | 意味(RFC 6749) | 写真の例 | Microsoft の場合 |
|---|---|---|---|
| リソースオーナー | 守られたデータへのアクセスを許せる人。たいていは利用者本人 | あなた | サインインするユーザー |
| クライアント | 持ち主の許可を受けて、持ち主の代わりにデータを頼むアプリ | 印刷サービス | Entra ID に登録したアプリ |
| 認可サーバ | 持ち主を確かめ、許可を受けて、クライアントにアクセストークンを出すサーバ | 写真サイトのログイン・許可の係 | Microsoft ID プラットフォーム(Entra ID) |
| リソースサーバ | 守られたデータを持ち、アクセストークンを確かめてリクエストに応じるサーバ | 写真サイトの API | Microsoft Graph や、自社の Web API |
「クライアント」という言葉に注意してください。OAuth 2.0 のクライアントは、人が使うパソコンではなく、データを取りに行くアプリのことです。Web サーバで動くアプリも、スマホのアプリも、別の API を呼ぶ API も、クライアントになります。
認可サーバとリソースサーバは、同じ会社のサービスのこともあれば、別々のこともあります。Microsoft の場合は、Entra ID がトークンを出し、Microsoft Graph などの API がそのトークンを確かめます。
全体の流れ
RFC 6749 は、4つの役割の間のやり取りを (A)〜(F) の6つの手順で説明しています。
- (A)(B) クライアントが、持ち主に「写真を読んでいいですか」と許可を求め、許可の証(グラント)を受け取る。
- (C)(D) クライアントが、許可の証を認可サーバに見せてトークンを頼む。認可サーバは、クライアントを確かめ、許可の証が正しければアクセストークンを出す。
- (E)(F) クライアントが、アクセストークンを付けてリソースサーバにデータを頼む。リソースサーバはトークンを確かめ、正しければ応じる。
大事なのは、リソースサーバは持ち主のパスワードを知らないことです。トークンだけを見て判断します。また、(A)(B) は持ち主とクライアントが直接やり取りする形で描かれていますが、実際には認可サーバのサインイン画面と同意画面を通して行うのが一般的です。認可コードという方式では、持ち主は認可サーバにだけサインインするので、パスワードはクライアントに一切渡りません。
2つの窓口:認可エンドポイントとトークンエンドポイント
認可サーバは、トークンを出すだけの係ではありません。RFC 6749 は認可サーバを「持ち主を確かめ、許可をもらったうえで、クライアントにアクセストークンを出すサーバ」と定義しています。つまり、本人を確かめる、許可をもらう、アプリを確かめてトークンを出す、の3つの仕事をします。
この仕事を、認可サーバは2つの窓口(エンドポイント)に分けて受け持っています。分け方の決め手は、誰が来る窓口かです。
| 項目 | 認可エンドポイント | トークンエンドポイント |
|---|---|---|
| 誰が来るか | 人(ブラウザ)。アプリがブラウザをここへ移動させる(リダイレクト) | アプリ(クライアント)が直接呼ぶ |
| ここでする仕事 | 本人を確かめる(サインイン)。アプリに許可するかを聞く(同意) | アプリを確かめる。許可の証をアクセストークンに換える |
| 出すもの | 許可の証(認可コード) | アクセストークン(場合によりリフレッシュトークンも) |
| 画面 | サインイン画面や同意画面が出る | 画面は出ない。プログラムどうしのやり取り |
認可コードという方式で、実際にどちらの窓口がいつ使われるかを並べると次のようになります。前半はブラウザ経由で人が画面を操作し、後半はアプリが直接トークンエンドポイントとやり取りします。
- ①〜④ 認可エンドポイント:アプリは人をサインイン画面へ案内するだけで、パスワードには触れません。人がサインインして「許可」を押すと、認可サーバは許可の証(認可コード)を付けてブラウザをアプリへ戻します。
- ⑤⑥ トークンエンドポイント:アプリは受け取った許可の証を、自分自身の証明と一緒にトークンエンドポイントへ送り、アクセストークンに換えます。クライアントはふつう、ここで自分自身を確かめてもらいます。トークンはブラウザを通らずに、アプリに直接渡ります。
- ⑦ アプリは受け取ったアクセストークンを付けて API を呼びます。
すべての方式が両方の窓口を使うわけではありません。人がいないクライアントクレデンシャルでは、サインインも同意の画面もないので、アプリはトークンエンドポイントだけを使います。アクセストークンの期限が切れたときに、リフレッシュトークンで取り直すのもトークンエンドポイントです。
Microsoft のドキュメントにある、Entra ID の2つのエンドポイントの例です。<issuer> には、テナント ID やドメイン名、common などが入ります。アプリ登録の Entra ID ›› App registrations ›› <アプリ> ›› Endpoints でも確かめられます。
Entra ID のエンドポイントの例(Microsoft のドキュメントより)
# Authorization endpoint - used by client to obtain authorization from the resource owner. https://login.microsoftonline.com/<issuer>/oauth2/v2.0/authorize # Token endpoint - used by client to exchange an authorization grant or refresh token for an access token. https://login.microsoftonline.com/<issuer>/oauth2/v2.0/token
アクセストークン:範囲と期限のある通行証
RFC 6749 は、アクセストークンを「守られたデータにアクセスするための資格情報」で、「クライアントに出された許可を表す文字列」だと説明しています。トークンには、どの範囲を、いつまで許すかが結び付いています。
- 範囲(scope):何をしてよいか。クライアントは、認可エンドポイントやトークンエンドポイントで範囲を指定できます。
- 期限:アクセストークンには期限があり、切れたら取り直します。取り直しに使うのがリフレッシュトークンで、Microsoft は、リフレッシュトークンを機密の情報として扱うよう書いています。
- 宛先:OAuth 2.0 のセキュリティのベストプラクティス(RFC 9700)は、アクセストークンを特定のリソースサーバ向けに絞ることを勧めています。
「Bearer=持参人」のトークン
OAuth 2.0 でよく使われるのは Bearer トークンです。RFC 6750 は、Bearer トークンを「持っている人なら誰でも、ほかの持ち主と同じように使えるトークン」と定義しています。電車の切符のように、持っている人が使えるということです。
アクセストークンを付けて API を呼ぶ例(RFC 6750 より)
GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM
持っているだけで使えるということは、API の側からは「誰が持ってきたか」を区別できないということです。正しいアプリが持ってきても、写しを手に入れた誰かが持ってきても、トークンが正しければ同じように応じてしまいます。
そのため、漏れないようにすることが何より大事です。RFC 6750 は、Bearer トークンを付けたリクエストには必ず TLS(https)を使うよう求めています。図7の下のように、運び方・しまい方・期限・宛先と範囲の4つで守りを重ねます。さらに RFC 9700 は、トークンを特定の持ち主(送り手)に縛るしくみを使うことも勧めています。Microsoft の Entra ID が出すアクセストークンも Bearer で、形式は JWT です。
トークンの中身はリソースサーバが見るもの
アクセストークンは、アプリが受け取って API に渡しますが、中身を見るのはアプリではありません。Microsoft のドキュメントは、クライアントはアクセストークンを「中身の分からない文字列」として扱い、確かめようとしないこと、確かめるのはリソースサーバの役目であることを書いています。トークンの中身は、宛先の API のためのものだからです。
- アプリ(クライアント):トークンを封筒のように、封をしたまま運びます。期限や範囲は、トークンと一緒に返ってくる情報(
expires_inなど)で知ります。Microsoft のサービス向けのトークンは、JWT として読めない形式だったり、暗号化されていたりすることもあります。 - API(リソースサーバ):届いたトークンの封を開けて確かめます。Microsoft の Web API 向けのライブラリは、宛先(この API 向けか)、発行元(信頼できる認可サーバか)、期限、署名(書き換えられていないか)を確かめ、そのうえで範囲(
scp)やロール(roles)で、その操作をしてよいかを判断します。
トークンのもらい方(グラント)
RFC 6749 は、許可の証(グラント)のもらい方として4つの種類を決めています。ただし、そのあとに出たセキュリティのベストプラクティス(RFC 9700)で、2つは使わない扱いになりました。
| グラント | どんなときに使うか | 今の扱い(RFC 9700) |
|---|---|---|
| 認可コード | 人がサインインして許可し、アプリがその人の代わりに API を呼ぶ。持ち主は認可サーバにだけサインインするので、パスワードはアプリに渡らない | 主に使う。PKCE を組み合わせる(公開クライアントは必須、機密クライアントも推奨) |
| クライアントクレデンシャル | 人はいない。アプリが自分の管理する範囲のデータに、アプリ自身としてアクセスする | 使う |
| インプリシット | ブラウザのアプリが、認可エンドポイントから直接トークンを受け取る | 使わないことが推奨(SHOULD NOT) |
| リソースオーナーパスワードクレデンシャル | アプリが利用者のパスワードを受け取り、それでトークンを取る | 使ってはいけない(MUST NOT) |
パスワードを受け取るグラントが「使ってはいけない」になっているのは、図1の「パスワードを渡すやり方」に戻ってしまうからです。今は、人がいる場面では認可コード、人がいない場面ではクライアントクレデンシャル、と覚えておけば十分です。
人がサインインする場合(認可コード)の流れは、図5で見たとおりです。人がサインインしない場合(クライアントクレデンシャル)は、次のようにずっと短くなります。Microsoft の場合で並べます。
- ⓪ 事前の準備:アプリケーションのアクセス許可は、管理者が同意しておきます。人が関わるのはここだけです。
- ①〜③:アプリはトークンエンドポイントに、アプリ自身の証明(クライアントシークレットや証明書)と範囲を送ります。Microsoft Graph を呼ぶなら、範囲は
https://graph.microsoft.com/.defaultです。.defaultは「管理者が同意したアプリの許可をまとめて入れてほしい」という意味です。 - ④〜⑥:アプリはトークンを付けて API を呼びます。API はトークンを確かめ、アプリに付いた許可(
roles)で判断します。
図5と比べると、ブラウザもサインイン画面も出てこず、認可エンドポイントも使いません。その代わり、アプリ自身の証明が人のサインインの代わりになるので、シークレットや証明書の管理が大事になります。Microsoft は、シークレットより証明書を使うことを勧めています。
人の代わりか、アプリ自身か
2つのグラントの違いは、Microsoft のドキュメントの「委任されたアクセス」と「アプリのみのアクセス」の説明で見るとわかりやすくなります。ここからは Microsoft の場合の話です。
| 項目 | 委任されたアクセス許可 | アプリケーションのアクセス許可 |
|---|---|---|
| 誰として | サインインした人の代わり | アプリ自身(人はいない) |
| できる範囲 | その人ができないことは、アプリもできない | 許可に結び付いたデータなら何でも |
Files.Read.All の例 | その人が読めるファイルだけ読める | テナントのどのファイルでも読める |
| 誰が同意できるか | 自分のデータならユーザー、全員分なら管理者 | 管理者だけ |
| 別の呼び方 | スコープ | アプリロール |
同じ Files.Read.All でも、委任とアプリケーションでは届く範囲がまったく違います。アプリケーションのアクセス許可は強いので、管理者しか同意できないようになっています。
同意(コンセント)
図3の (A)(B) で持ち主が「許可する」場面が、同意(コンセント)です。Microsoft の場合、アプリに初めてサインインしたときなどに、アプリが求めるアクセス許可の一覧と、アプリの発行元の情報が表示され、ユーザーは許可するかどうかを選びます。強い権限を求めるアプリには、管理者の同意が必要になります。
OAuth 2.0 は「認可」のしくみ
OAuth 2.0 は「アプリに何をさせてよいか」を決める認可のしくみで、「誰がサインインしたか」を確かめる認証のしくみではありません。Microsoft の API Management のドキュメントも、OAuth 2.0 は認証のプロトコルではなく、ユーザーの認証やシングルサインオンを足す OpenID Connect と一緒に使われることが多いと説明しています。
OpenID Connect は OAuth 2.0 を広げて、ID トークンという「誰がサインインしたか」を表すトークンを足します。
では、OAuth 2.0 と OpenID Connect は、実際の流れのどこで分かれるのでしょうか。人がサインインして API も呼ぶ、よくある場面を順に並べると次のようになります。白抜きの札が OAuth 2.0 の部分、塗りつぶしの札が OpenID Connect が足す部分です。
- 流れそのものは OAuth 2.0:①〜⑤は、図5で見た認可コードの流れと同じです。Microsoft のドキュメントも、OpenID Connect のサインインの要求は、OAuth 2.0 の認可コードの最初の手順とよく似ていると説明しています。
- OpenID Connect が足すもの:①で範囲に
openidを入れると、⑤でアクセストークンと一緒に ID トークンが届きます。⑥でアプリが ID トークンを確かめ、「誰がサインインしたか」を知ります。これがサインイン(認証)です。 - API を呼ぶのは OAuth 2.0:⑦⑧で API に見せるのはアクセストークンです。ID トークンは API には渡しません。
OpenID Connect は新しい流れを作るのではなく、OAuth 2.0 の流れに「誰がサインインしたか」を運ぶ ID トークンを足したもの、と考えると分かりやすくなります。アクセストークンは API に見せるもの、ID トークンはアプリ自身が読むもの、と覚えると混ざりません。Microsoft も、ID トークンをリソースへのアクセスの認可には使わないよう書いています。
ID トークンがあると、アプリに何ができるのか
アクセストークンだけでも、アプリは API を呼べます。では、ID トークンがあると何がうれしいのでしょうか。違いは、アプリが自分で「誰がサインインしたか」を確かめられるかどうかです。
アクセストークンは API に宛てた通行証です。図8で見たとおり、アプリは中身を読みません。そのため、アクセストークンだけでは、アプリは「いま誰が使っているのか」を自分では確かめられません。
ID トークンは、アプリ自身に宛てて出されます。Microsoft のドキュメントも、ID トークンは、アプリがユーザーをサインインさせるときに使い、ユーザーの基本的な情報を得るためのものだと説明しています。アプリは ID トークンを確かめることで、次のことができるようになります。
| できること | 使う情報 | たとえば |
|---|---|---|
| ログインした状態を作る | ID トークンを確かめて本人と分かったら、アプリのセッションを始める。Microsoft は、セッションの長さを ID トークンの期限(exp)に合わせるよう書いている | 社内ポータルに一度入れば、しばらくはそのまま使える |
| 名前やメールアドレスを出す | 範囲に profile や email を入れると、名前やメールアドレスが ID トークンに入る | 画面の右上に「○○さん」と出す |
| アプリのデータを本人に結び付ける | tid(テナント)と oid(ユーザー)の組み合わせは変わらない値。Microsoft は、これをデータのキーに使うよう勧めている | 申請の履歴や設定を、その人のものとして保存する |
| ほかのアプリとシングルサインオン | Microsoft のドキュメントは、OpenID Connect は ID トークンでアプリどうしのシングルサインオンを実現すると説明している | Entra ID に一度サインインすれば、別の業務アプリにも入れる |
アプリ宛てだから、アプリが確かめられる
ID トークンとアクセストークンの大きな違いは、宛先です。
| 項目 | ID トークン | アクセストークン |
|---|---|---|
| 誰宛てか | アプリ自身(aud がアプリのクライアント ID) | API(aud が API) |
| 中身を読むのは | アプリ | API。アプリは読まない |
| 分かること | 誰がサインインしたか | アプリに何が許されたか |
| 見せる相手 | どこにも見せない。アプリの中で使う | API に見せる |
アプリは ID トークンの署名を確かめたうえで、自分宛てか(aud が自分のクライアント ID か)、期限内か、自分が送ったサインインの要求への答えか(nonce が要求のときと同じか)を確かめます。自分宛てだと確かめられるから、「この人がサインインした」と信じてよいわけです。
- サインインだけしたいアプリ:範囲を
openidにして、ID トークンだけをもらえば済みます。 - API も呼びたいアプリ:図14のように、ID トークンとアクセストークンの両方をもらいます。
ID トークンは「誰か」を表すもので、API への通行証ではありません。Microsoft も、ID トークンをリソースへのアクセスの認可には使わないよう書いています。API にはアクセストークンを見せます。また、Microsoft のドキュメントは、ID トークンを確かめるのはサーバで動く機密クライアントであるべきだとしています。ブラウザやスマホのように利用者の手元で動くアプリでは、確かめに使う鍵を書き換えられるおそれがあり、確かめても効果がないためです。
動かす前の準備:認可サーバに登録しておくこと
ここまでの流れは、いきなり動くわけではありません。動かす前に、アプリと API をそれぞれ認可サーバに登録しておく必要があります。RFC 6749 も、クライアントはプロトコルを始める前に認可サーバに登録する、と書いています。登録の方法は認可サーバごとに違うので、ここからは Microsoft(Entra ID)の場合で見ます。
| 準備 | 何を設定するか | ねらい |
|---|---|---|
| ① アプリの登録 | アプリを登録すると、クライアント ID が割り当てられる。リダイレクト URI(認可コードを返す先)と、アプリ自身の資格情報(クライアントシークレット、または証明書の公開鍵)を登録する | 認可サーバが「どのアプリか」「本物のアプリか」「コードをどこへ返すか」を判断できるようにする。クライアント ID は秘密ではない |
| ② API の登録 | API も登録し、Expose an API でアプリ ID URI(例:api://<クライアント ID>)と範囲(スコープ)を決める。人がいない呼び出しを受けるなら、App roles でアプリロールも決める | トークンの宛先と、アプリに許せる操作の一覧を作る |
| ③ 許可と同意 | アプリの登録に、使いたい API の許可を付ける。ユーザーや管理者が同意する(アプリケーションの許可は管理者だけ) | どのアプリに、どの範囲を許すかを決める |
| ④ 署名の確かめ方 | API は、認可サーバが公開しているメタデータから、トークンの署名を確かめる公開鍵を取る | トークンが本物で、書き換えられていないことを確かめる |
証明書や鍵の受け渡しは要る?
「事前に証明書を交換しておく」ような作業があるかどうかは、どの鍵の話かで分かれます。
- アプリが証明書で自分を証明する場合:アプリの登録に、証明書の公開鍵をアップロードしておきます。秘密鍵はアプリが持ちます。Microsoft は、クライアントシークレットより証明書を使うことを勧めています。これはアプリと認可サーバの間の、一度きりの準備です。
- トークンの署名を確かめる鍵:認可サーバはトークンを秘密鍵で署名し、対応する公開鍵を公開しています。API は、OpenID Connect のメタデータ(下の URL)にある
jwks_uriから公開鍵を取ります。手で受け渡しするものではありません。 - アプリと API の間:鍵や証明書を直接交換する必要はありません。どちらも認可サーバとだけつながり、認可サーバを信頼の中心にします。
Entra ID の OpenID Connect のメタデータの場所(Microsoft のドキュメントより)
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
Microsoft の署名の鍵は定期的に入れ替わり、緊急時にはすぐに入れ替わることもあります。入れ替わりの間隔は決まっていません。Microsoft は、公開鍵を手で設定して固定するのではなく、標準のライブラリでメタデータから自動で取り直すよう勧めています。公開鍵を手で更新するアプリは、安全性も信頼性も下がるとしています。
注意点
| 注意点 | 理由と対策 |
|---|---|
| トークンを漏らさない | Bearer トークンは持っている人が使える。必ず HTTPS で運び、ログや画面に出さない。リフレッシュトークンも機密として扱う |
| 範囲は必要な分だけ | 範囲が広いほど、漏れたときの影響が大きい。特にアプリケーションのアクセス許可は、テナント全体に届くことがある |
| 古いグラントを使わない | パスワードを受け取るグラントとインプリシットは、RFC 9700 で使わない扱いになっている |
| リダイレクト先を正確に登録する | RFC 9700 は、認可サーバがリダイレクト先の URI を文字列の完全一致で確かめることを求めている。アプリ登録のリダイレクト URI は、使うものだけを正確に登録する |
| 同意画面をよく見る | 同意すると、アプリはその範囲でデータにアクセスできるようになる。求められているアクセス許可と、アプリの発行元を確かめてから許可する |
企業での例
| 場面 | OAuth 2.0 での形 | 押さえどころ |
|---|---|---|
| 社内の Web アプリが、使っている人のメールや予定を Microsoft Graph で読む | 委任されたアクセス許可。認可コードでトークンを取る | アプリは、その人が見られるものしか見られない |
| 夜間のバックアップや自動化の仕組みが、Microsoft Graph を呼ぶ | アプリケーションのアクセス許可。クライアントクレデンシャルでトークンを取る | 管理者の同意が必要。範囲がテナント全体になりやすいので、必要な許可だけにする |
| 社外の SaaS に「Microsoft でサインイン」し、SaaS が予定表を読む | SaaS がクライアント、Entra ID が認可サーバ、Microsoft Graph がリソースサーバ | 同意画面で、求められているアクセス許可と発行元を確かめる |
| 自社の API を、Entra ID のトークンで守る | 自社の API がリソースサーバ | API でトークンを確かめる。API Management のドキュメントも、発行元(issuer)と宛先(audience)の確認を挙げている |
まとめ
| 項目 | 内容 |
|---|---|
| 何をするしくみか | パスワードを渡さずに、範囲と期限のある通行証(アクセストークン)をアプリに渡す |
| 4つの役割 | リソースオーナー(持ち主)、クライアント(アプリ)、認可サーバ(通行証を出す係)、リソースサーバ(データを持つ API) |
| 流れ | 許可をもらう → 許可の証をトークンに引き換える → トークンを付けて API を呼ぶ |
| アクセストークン | 範囲・期限・宛先がある。Bearer なので漏らさない(HTTPS で運ぶ) |
| グラント | 人がいるなら認可コード(PKCE と組み合わせる)、人がいないならクライアントクレデンシャル。インプリシットとパスワードのグラントは使わない |
| 動かす前の準備 | アプリと API を認可サーバに登録する。API は認可サーバの公開鍵をメタデータから自動で取る。アプリと API の間で鍵を交換する必要はない |
| 認可と認証 | OAuth 2.0 は認可。サインインは OpenID Connect が ID トークンで足す。ID トークンはアプリ宛てなので、アプリが「誰がサインインしたか」を確かめ、ログインした状態や本人のデータに使える |
参考にした資料
この記事は、次の標準と公式ドキュメントで内容を確かめて書きました。仕様や対応状況は変わることがあるので、最新の情報はリンク先で確かめてください。
- RFC 6749: The OAuth 2.0 Authorization Framework(IETF):パスワードを渡すやり方の問題と写真の印刷の例、4つの役割と認可サーバの定義、クライアントの登録、(A)〜(F) の流れ、4つのグラント、アクセストークンとリフレッシュトークン、範囲、2つのエンドポイント、機密クライアントと公開クライアント
- RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage(IETF):Bearer トークンの定義、Authorization ヘッダの例、TLS を必ず使うこと
- RFC 9700: Best Current Practice for OAuth 2.0 Security(IETF):インプリシットとパスワードのグラントの扱い、PKCE、リダイレクト URI の完全一致、トークンの宛先の制限
- OAuth 2.0 and OIDC authentication flow in the Microsoft identity platform・Overview of permissions and consent in the Microsoft identity platform・Microsoft identity platform and OAuth 2.0 authorization code flow・OpenID Connect on the Microsoft identity platform(Microsoft Learn):役割と Microsoft での対応、トークンの種類、エンドポイントの例、委任とアプリのみのアクセス、同意、token_type が Bearer であること、自分のものではない API のトークンを読まないこと、OpenID Connect のメタデータと jwks_uri、トークンエンドポイントで認可コード・リフレッシュトークン・クライアントの資格情報をトークンに換えること、OpenID Connect と ID トークン
- Access tokens in the Microsoft identity platform・Protected web API: Code configuration・Implement authorization in web APIs with Microsoft.Identity.Web(Microsoft Learn):クライアントはトークンを中身の分からない文字列として扱うこと、確かめるのはリソースサーバであること、宛先・発行元・期限・署名の確認、scp と roles
- Microsoft identity platform and the OAuth 2.0 client credentials flow・Acquire tokens to call a web API using a daemon application(Microsoft Learn):トークンエンドポイントへの要求、シークレット・証明書・フェデレーション資格情報、.default の範囲、管理者の同意
- Configure an application to expose a web API・Quickstart: Call a web API that is protected by the Microsoft identity platform・Signing key rollover in the Microsoft identity platform(Microsoft Learn):API の登録とアプリ ID URI・範囲、アプリロールの公開、署名の鍵の入れ替わりとメタデータからの自動取得
- ID tokens in the Microsoft identity platform(Microsoft Learn):ID トークンの確かめ方(署名、期限、宛先、nonce)、確かめるのは機密クライアントであること
- Authentication and authorization to APIs in Azure API Management・Manage tokens for Zero Trust(Microsoft Learn):OAuth 2.0 は認証のプロトコルではないこと、発行元と宛先の確認、ID トークンを認可に使わないこと、tid と oid をキーにすること、セッションを ID トークンの期限に合わせること、profile・email の範囲で足される情報
あとがき
OAuth 2.0 は、最初に読んだとき「認可コード」「グラント」「スコープ」と用語が多くて身構えてしまいました。ただ、RFC の最初にある写真の印刷の例に戻ると、やりたいことは「パスワードを渡さずに、写真を読むことだけ任せたい」という素朴な話でした。同じ Files.Read.All でも、委任とアプリケーションで届く範囲がまったく違うのは、Entra ID でアプリ登録をするときにいちばん気をつけたい点だと感じています。
コメント