はじめに
Qiita初投稿です。
普段はNode.JSやReact、Azureを触っている二年目エンジニアです。
今回はOAuth2.0について自分の理解と整理のためにまとめます。
アジェンダ
- 従来の認証モデル
- OAuth2.0
- OAuth2.0の登場人物
- 認可フローについて
- 認可コードグラントフローについて
- 認可コードグラントフローのまとめ
- さいごに
従来の認証モデル
従来のクライアント/サーバー認証モデルでは、クライアントがリソースオーナの資格情報を使用し、
サーバーで認証することにより、サーバー上のアクセス制限付きリソース(保護されたリソース)を要求をしていました。
図は個人資産管理アプリ※1 を想定して作っています。
今後の図は、基本的に個人資産管理アプリを想定し図を書いています。
このフローでは以下のような問題が生じます。
- Fintech企業にID,PWを渡しているため、ずさんな管理を行っているFintech企業から、ID・PWの漏洩 する可能性がある
- リソースオーナはFintech企業に、インターネットバンキングの 機能を制限 させることができない
(残高の照会のみさせる、といったことはできない)
OAuth2.0の概要
問題点を解決するために、先程洗い出した問題点を逆転の発想でみてみると、
- ID、PWをFintech企業に渡さず に情報を取得できるようにする
- リソースオーナが 許可した機能のみ Fintech企業に利用させる (認可)
ことさえできればよさそうです。
この問題を解決することができる仕様がOAuth2.0です。
OAuth2.0はだいたい、以下のフローになっています。
- 銀行システムのクライアントであるFintech企業が、銀行システムの認可サーバと言うアクセストークンを発行してくれるサーバに発行依頼をします
- 発行依頼を受けた認可サーバは、アクセストークンの発行を行います
- クライアントは発行したアクセストークンを受け取ります
- リソースオーナの情報があるリソースサーバに、アクセストークンと一緒にリクエストを送ります
- 受け取ったアクセストークンが正しいものか検証を行い、オッケーだった場合、
- クライアントにレスポンスします。
こうすることで、
ID・PW を使用せずに情報をやり取りすることができます。
また、アクセストークンに使用できる機能の情報をもたせることで
機能を制限させる ことができます
OAuth2.0
もう少し詳細にOAuth2.0のフローを見ていきます。
どのようにしてユーザのクレデンシャル(ID、PW)を使わずに 限られたリソースにのみ 使用可にするのか、をもう少し具体的にまとめて行きます。
いきなりですが、認可についてはある程度仕様が決まっており、RFC 6749※2に記載されています。
OAuth2.0の登場人物
OAuth2.0の特性上、たくさんのシステムが出てきます。
そのため、一旦OAuth2.0の登場人物を整理し全体像の把握から行います。
認可フローについて
実はOAuth2.0には4種類のフローが定義されています。
全部説明をしていると、ながーくなってしまうので、今回はその中でも一番多く実装されているであろうAuthorization Code Grant(認可コードグラント)についてまとめます。
認可コードグラントフローについて
認可フローは以下の順で進んでいきます。
※誰が何をしているのか分かりやすくするために、RFC6749で定義されていない内容もあえて記載しています。
フローの目次
0 クライアントの登録
- リソースオーナーがクライアントを通してAPIプロバイダのサービスを利用するための何らかのアクションを行う
- 認可リクエスト
- リソースオーナの認可および認可コードの発行
- アクセストークンリクエスト
- リソース処理のリクエスト
0.クライアントの登録
①フローを開始する前に、クライアントの情報を認可サーバに登録しておきます。
認可サーバに誰がリクエストを行っているのかの判定、3でリダイレクトする先の情報を事前に登録しておくために必要です。
1. リソースオーナーがクライアントを通してAPIプロバイダのサービスを利用するための何らかのアクションを行う
①フローを開始する起因となるアクションをユーザが起こします。
2. 認可リクエスト
ここから認可のフローがスタートします。
①フロントアプリケーションがクライアントのバックエンドに認可フローを必要としていることを伝えます。
②リクエストを受け取ったクライアントのバックエンドは、リソースオーナーにクライアントがリソースへのアクセス許可をもらうために、認可するか確認する画面(認可画面)のURIをレスポンスします。
③フロントアプリケーションは、取得したURIにリダイレクトを行い、
④認可画面を表示します。
3. リソースオーナの認可および認可コードの発行
①認可画面を通して、リソースオーナは認可サーバに向けてクライアントが自身のリソースにアクセスする許可を行います。
②クライアントにリソースをアクセスする許可を受けた認可サーバは、
③リダイレクトURIと認可コードを返却します。
④フロントアプリケーションは受け取ったリダイレクトURIに認可コードを持ってリダイレクトします。
4. アクセストークンリクエスト
①クライアントのバックエンドサーバは受け取った認可コードをもとに、認可サーバからアクセストークン取得リクエストを行います。
②リクエストを受け取った認可サーバはアクセストークン(リソースオーナのリソースにアクセスする権限を持つトークン)を返却します
5. リソース処理のリクエスト
①クライントは、リソースサーバにリソースの処理を行うリクエストを投げ、
②リソースサーバーは送られてきたアクセストークンが正しいトークンか検証を行います。
③正しい場合はリクエストに対する処理を行った上、結果をクライアントのバックエンドサーバに返却します。
認可コードグラントフローのまとめ
以上が認可コードグラントフローです。
伝わりましたかね?
(というか、間違ってないですかね? 先輩エンジニアの皆さん。誤っているところがあったら教えてください。)
このようにすることで、クライアントは、リソースオーナーのクレデンシャル情報なしに、リソースに関する処理を行うことができ、リソースオーナーの権限で、クライアントにどこまでリソースを処理させるか制限させることができます。
さいごに
私が初めて認可に触れた際、結局「誰が何やってんねん」となり、「どゆこと!?」ってなってました。
そのため、今回は1リクエストごとに図を分け、誰が何をしているのかがわかりやすくなるようにまとめました。
次回は、体力的にまとめられなかった、他の3つのフローの違いと使いみち、OAuth2.0脆弱性についてまとめようと思います。
脚注
※ 1 家計簿アプリ
とは
個人資産管理アプリ(家計簿アプリ)
銀行口座の残高や電子マネーの残高、クレジットカードの利用額等を一元的に管理し、自分の資産をわかりやすく表示してくれるアプリの総称
※ 2 RFC
とは
RFCとはRequest For Commentsの略で、IETF(Internet Engineering Task Force)によって、
管理されている、Webに関する標準化についてまとめられたドキュメントです。
RFCに記載されている内容すべてが、標準プロトコルとして確立されているわけではなく、
将来的に標準化されるであろう技術を示し、評価を求める段階のもの(PS:Proposed Standard)、
標準化の仕様として十分運用できる草案段階のもの(DS:Draft Standard)、
十分な運用経験が積まれ標準プロトコルとして確立されたもの(STD:Standard)
の3つが記載されています。
基本的に私達エンジニアが実際に使用するのは、すでに標準プロトコルとして確立している、STDが主となり、
HTTPやIP、OAuth2.0もSTDとしてRFCに記載されています。