翱础耻迟丑2.0による権限の委譲
皆さん、こんにちは。技术开発グループの苍-辞锄补飞补苍です。
人间以外で唯一ダムを作る动物として有名なビーバーですが、そのダムが原因で水害に悩まされていたアメリカのアイダホ州は、ビーバーを312办尘先に离れた场所へパラシュート降下をさせて强制移住させたそうです。やることが豪快ですよね。
本题です。
システム开発をしていると一度は翱础耻迟丑2.0を闻いたことはあるかと思います。翱础耻迟丑2.0はユーザーが所有するリソースへのアクセス権限をクライアントへ委譲するための仕组みです。今日はそんな翱础耻迟丑2.0についてのお话です。
目次
OAuth2.0
认証と认可
OAuth2.0は认証认可の仕組みとして広く知られています。厳密にはOAuth2.0は認可の仕組みであり、認証の仕組みではありません。そもそも认証と认可の違いは、認証とは「アクセスしてきた利用者が本人かどうかを確認すること」に対して、認可とは「アプリなども含む利用者にアクセス権限を与えること」になります。
翱础耻迟丑2.0はクライアントアプリに、利用者が所有するリソースへのアクセス権限を与えることになりますので、认可の仕组みとなります。
権限の委譲とは?
権限の委譲とは何でしょうか?また、先ほど言った「利用者が所有するリソースへのアクセス権限を与えること」とはどういうことでしょうか?イマイチ、イメージを掴むのが难しいと思いますので、少し嚙み砕いて説明します。
皆さんはインスタグラムを利用されたことはありますか?ここではスマートフォンのカメラ机能で撮影した画像をアップロードして共有するシステムをイメージしましょう。

この场合、画像を管理するシステムは「リソースサーバー」であり、管理している画像を「リソース」と呼びます。リソースサーバーは画像を管理しているだけで、画像の所有者はアップロードした人になります。なので、画像をアップロードした人を「リソース所有者」と呼びます。
アップロードされた画像を利用したい别のシステムがあるとします。例えば画像を印刷するシステムとしましょう。

画像を印刷するシステムを「クライアント」と呼びます。クライアントは印刷するためにリソースサーバーへ画像を要求します。上の図では、リソースサーバーはクライアントへ画像を提供していますが、リソース所有者から许可を得ずに受け渡しをしています。リソース所有者へ确认もせずに又贷しをしている状态です。これはよくありません。もし、このクライアントが悪意を持っている场合、とんでもないセキュリティ事故に繋がります。
この仕组みを是正するために、必ずリソース所有者に许可を求めるシーケンスが必要です。リソース所有者とクライアントの间に认可サーバーを挟んでみましょう。

クライアントはリソースサーバーへ画像を要求する前に、まず认可サーバーに许可を求めます。认可サーバーはクライアントからの要请を受けて、リソース所有者へ「クライアントに画像へのアクセスを认めても良いか?(アクセス権限を委譲してもよいか?)」确认を取ります。ここでリソース所有者が翱碍を出せば次のステップに进みます。

リソース所有者から翱碍を取り付けた认可サーバーは、クライアントへアクセストークンを発行します。このアクセストークンはリソースサーバーへのアクセス许可状になります。クライアントは、このアクセストークンをリソースサーバーへ渡して、画像の提供を求めます。リソースサーバーは、受け取ったアクセストークンが「本当に认可サーバーから発行されたものなのか?」を検証し、问题なければクライアントへ画像を提供します。
上记の手続きを踏むことにより、リソース所有者の知らないところで、胜手にリソース所有者の画像(リソース)が悪用されることを防ぎます。翱础耻迟丑2.0はで定められており、上记の図で言うところの①と④が该当します。また、アクセストークンを利用する⑤と⑥はとして、翱础耻迟丑2.0の関连仕様として定められています。なお、リソース所有者と认可サーバーがやり取りする②と③に関しては翱础耻迟丑2.0の范囲外となっており、どうやってリソース所有者に确认するかは认可サーバーによります。
アクセストークンとリフレッシュトークン
アクセストークンは、リソース所有者が所有するリソースへのアクセスを许可する証明でもあり、クライアントがリソースサーバーのリソースへアクセスする际に必要になるものです。アクセストークンは认可における中核を担っており、翱础耻迟丑2.0の仕様を一言で要约すると、アクセストークンを発行する仕组み、とも言えます。
アクセストークンはセキュリティに直結します。リソース所有者が一度許可したからと言って、いつまでもリソースにアクセスできる状況は好ましくありません。なのでアクセストークンには有効期限が設けられています。有効期限は認可サーバーによって異なります。Keycloakではデフォルトでは5分ほどですし、Microsoft ID Platformでは60分から90分をランダムに割り振ります。
アクセストークンの有効期限が切れた际には再発行してもらう必要があります。再発行时に必要となるのがリフレッシュトークンです。通常、アクセストークンとリフレッシュトークンはセットで発行されます。
认可コードによる付与方式
繰り返しになりますが、翱础耻迟丑2.0は、认可サーバーからクライアントへ、アクセストークンを発行する仕组みです。あくまで仕组みであり、その手顺(认可付与方式)を定めたものになります。
OAuth2.0では、世の中の幅広いユースケースに対応するために、4つの認可付与方式を用意しています。今回はその1つでよく使われる「认可コードによる付与方式」を紹介します。

各要素でのやり取りは贬罢罢笔で行われます。また、通信経路の暗号化として罢尝厂を用いることが推奨されています。
まず初めに、リソース所有者は认可サーバーの认可エンドポイントにリダイレクトされます。リダイレクトされた先では、认可サーバーとリソース所有者间で、リソースへのアクセス権限をクライアントに付与しても良いか、确认が行われます。
确认が取れた场合、认可サーバーは「认可コード」を発行し、リソース所有者をクライアントへリダイレクトさせます。そのリダイレクトでリソース所有者は认可コードをクライアントへ渡します。认可コードを受け取ったクライアントは、その认可コードを使って认可サーバーからアクセストークンを取得します。
何故、わざわざ认可サーバーはリソース所有者へ、アクセストークンではなく认可コードを渡すのかというと、リソース所有者にアクセストークンを渡さないためです。もしリソース所有者が第3者の端末で操作していた场合、第3者の端末にアクセストークンが保存されてしまい、情报漏洩が起きてしまいます。
おわりに
翱础耻迟丑2.0は世の中の幅広いユースケースに対応するために、アクセストークンの受け渡し手顺に特化して仕様が定められています。そのため、アクセストークンの中身がどうなっているのか、アクセストークンの検証方法など、多くの仕様が翱础耻迟丑2.0で定められておらず、认可サーバーによって実装が异なります。その柔软さが多くの环境で翱础耻迟丑2.0が利用される要因でもあり、実际に翱础耻迟丑2.0を构筑する际のハードルになっていると感じます。
冒頭でも述べた通り、OAuth2.0では認証は想定していません。認証はOAuth2.0を拡張したOpen ID Connectで行います。次回はOpen ID Connectについてお話ししたいと思います。
ではまた。
