(※この記事は 別媒体に投稿した記事 のバックアップです。 canonical も設定しています)
2020-12-28
※この記事は別アカウント(hyiromori)から引っ越しました
最近、個人的に認証認可周りを学習していて、その過程でOAuth2.0について学習している内容をまとめた記事です。
世の中には既にOAuth2.0に関する優れた書籍やブログ記事が沢山ありますが、自分が学習する過程で色々なものを読むことでより理解が深まったと思うので、自分も学習したものをアウトプットすることで同じように学習している人の理解の助けになればと思い書きました。
まだ私も学習中なので、もし間違ったところなどあればコメント頂けるとありがたいです。
この記事内ではOAuth2.0で定義されているフロー の1つ、認可コードによる付与(Authorization Code Grant)についてまとめています。
たくさんの仕様をいきなり網羅的にまとめるのは難しいので、1つに絞って今回はまとめています。
OAuth2.0に定義されているフローの解説については、こちらの記事が参考になりました。
https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f
OAuth2.0は認可を行うためのプロトコルで、所有者の代わりにリソースへのアクセスを許可するためのプロトコルです。
もう少し具体的な例を出すと、エンドユーザーがあるサービスに対して別のサービスへのアクセスを許可するためのトークンを発行するための手段といった感じです。
(OAuth2.0は様々なケースに対応できるので、もちろん上記の具体的な例以外のシーンでも使用できます)
OAuthは認可のためのプロトコルですが、認証を行うためのプロトコルではありません。
ここを間違えると、セキュリティ上の大きなリスクが発生する場合があります。
認証と認可の違いについては以下の記事が参考になりました。
https://dev.classmethod.jp/articles/authentication-and-authorization/
また単なるOAuth2.0を認証に使ってしまうと、どういったセキュリティ上のリスクがあるのかは以下の記事が参考になりました。
https://www.sakimura.org/2012/02/1487/
OpenID Connect は OAuth2.0 の拡張規格で、認証を行うこともできるようになっています。(この辺りは別の記事でまとめる予定)
まとめました。
https://zenn.dev/hyiromori/articles/2021-01-30-oidc
OAuth2.0では複数の登場人物(サーバー)が連携して認可を行います。
保護対象のリソースを保持しているサーバーを指します。
保護対象のリソースは様々なものがあり一概にこれとは言えませんが、例えばGoogleフォトの画像や、SNSの投稿などをイメージすると分かりやすいかもしれません。
保護対象のリソースを所有している人を指します。
OAuth2.0を使ってアカウントを連携をしたいエンドユーザーとも言えると思います。
保護対象のリソースにアクセスするソフトウェアのことを指します。
こちらも対象は様々なので一概にこれとは言えませんが、Web開発者であればWebアプリと考えておくと理解しやすいかもしれません。
画像もWebブラウザをイメージしたものにしていますが、Webアプリ以外のクライアントも存在します。
リソースサーバーに信頼されたサーバーで、リソースオーナーの認証を行い、リソースサーバーに対するアクセストークンを発行できます。
OAuth2.0において重要な役割を果たすサーバーです。
認可コードによる付与(Authorization Code Grant)の流れをまとめます。
自分が学習している時に「もうちょっと具体的な例を使った説明がほしいな〜」と思っていたので、私が実際に試してみた以下の構成をベースに説明します。
また以下の点に注意してください。
state
やPKCE関連のパラメーターなどはあえて省いています)Googleと連携したい時に、クライアントから必要なパラメーターを付与して、Googleの認可サーバーへのリダイレクトさせます。
リダイレクトで行う理由は、クライアントを識別したりする情報を付与してGoogleの認可サーバーにアクセスさせるためです。
クライアント(Webアプリ)内のリンクなどをクリックすると、リダイレクト専用のエンドポイント(例: /request_authorize
)にアクセスします。
GET /request_authorize HTTP/1.1
Host: https://client.example.com
このエンドポイントからは必要な情報をクエリパラメーターにセットされたURLが返却されて、Googleの認可サーバーへリダイレクトします。
HTTP/1.1 302 Found
Location: https://accounts.google.com/o/oauth2/v2/auth?client_id=(CLIENT_ID)&redirect_uri=https%3A%2F%2client.example.com%2Fcallback&scope=email&response_type=code
リダイレクト用のURLに付与されているクエリパラメーターを解説します。
OAuthの設定をした際に発行されるクライアントIDです。
どのクライアントが認可を要求しているかを識別するために使用されます。
リソースオーナーが連携を許可した後にリダイレクトされるURLです。
自由にリダイレクトURLが設定できてしまうと、悪意あるサイトに認可の情報が漏れてしまうため、事前に設定されたURLと一致させる必要があります。
何に対するアクセスの認可を要求するかを表しています。
リソースオーナーに対して、要求されている認可を許可してよいかどうかを確認されます。
リソースオーナーは必要に応じてパスワードなどで認証を行い、要求されているスコープを確認して、問題なければ許可します。
Googleでの例 ⬇
許可されると、アクセストークンを発行するための認可コードを発行して、クライアントへリダイレクトします。
先に説明したとおり認可コードが外部にもれないよう、リダイレクトは事前に設定されたURLのみ可能です。(大事なことなので2回書きました)
以下のように認可コードをクエリパラメーターに設定された状態でリダイレクトします。
HTTP/1.1 302 Found
Location: https://client.example.com/callback?code=(認可コード)
クライアント(Webアプリ)で定義されたエンドポイント(例: /callback
)に認可コードが渡されます。
GET /callback?code=(認可コード) HTTP/1.1
Host: https://client.example.com
リダイレクト時に付与された認可コードを認可サーバーに渡して、アクセストークンを取得します。
取得したアクセストークンを使って、保護されたリソースにアクセスします。
なるべくOAuth2.0の概要が分かりやすいように、最低限のものに絞って書いてみました。
実際に使うには情報が不足していると思いますが、OAuth2.0の理解の助けになれば幸いです。
学習する過程で参考になった資料をまとめておきます。