どうもこんにちは。
今回は、OAuthについてちゃんと理解をしなきゃいけないなぁと思い、理解を深めるために記事を書きました。
ところでOAuthってなんて読むん?ググったら「オーオースですよ」って言われたけど。良いんか?「オーオース」で。まぁ「認証認可のおおーす的なやつ」って言えば伝わるか。
この記事は、検証結果は存在しません。(いつかやります。)
整理のための記事です。
認証・認可とは?
まず、OAuthを学ぶ前に、認証と認可の違いについて整理しておくことが必要かなと思います。
確かに英語で書いても似ているので、混乱しますよね。
認証: Authentication
認可: Authorization
認証
認証は、「あなたは誰?」を確認すること です。
例えば、皆さんがよく使っているXのログイン画面でユーザIDとパスワードを入れると思います。これは「認証」です。
ログイン画面
↓
メールアドレス・パスワードを入力
↓
「この人は田中さんだ」と確認
認証が通らない場合の、HTTPステータスコードは「 401 」が一般的ですね。
認可
一方で、認可は、「あなたは何をしていい?」を決めること です。
例えば、「田中さんは管理者だからシステム設定画面を開くことができるが、高菜さんは一般ユーザだからシステム設定画面を開くことはできない」のようなことです。
田中さんがシステム設定画面を開こうとする
↓
「田中さんは権限を持っている」からよかろう
↓
田中さんがシステム設定画面を開くことができる
高菜さんがシステム設定画面を開こうとする
↓
「高菜さんは権限を持っていない」からブロック
↓
高菜さんがシステム設定画面を開くことができない
権限やロール/ポリシーに近いことをしているのが、「認可」ですね。
認可が通らない場合の、HTTPステータスコードは「 403 」が一般的ですね。
OAuthとは
上記を理解した上で、OAuthについて理解をしていきましょう。
まず、OAuthは本来「認証」の仕組みではなく、「認可」の仕組みになります。
さらに詳細を詰めると、「パスワードを渡さずに、別のサービスへ限定的な権限を与える仕組み」がOAuthの仕組みです。
例えば、人間がGoogleカレンダーにアクセスするとします。その場合、以下のような流れで認証認可が行われます。
- Googleカレンダーを開く
- Gメールアドレスとパスワードを入力する
- ログインする
- 日程の確認や追加を行う
これをAIが行うとしたらどうなるでしょう?文頭に「AIが」を置いてみますね。
- AIがGoogleカレンダーを開く
- AIがGメールアドレスとパスワードを入力する
- AIがログインする
- AIが日程の確認や追加を行う
どうでしょう?特に2番目がリスクじゃないでしょうか。AIにGメールアドレスとパスワードを渡してしまうのはセキュリティ的にOUTです。(悪用されるリスクが高まる)
このリスクを解決するのが、OAuth です。
必要なものはアクセストークン
私たちは、AIを含むシステムが外部のサービスにアクセスできるようにするために、ログイン情報ではなくアクセストークンを設定して渡しておく必要があります。
このアクセストークンには、「あなたはこの操作の権限を持っています」というような情報を持っています。
例えば、AIに「カレンダーの参照だけができる権限を持った」アクセストークンを渡しておくとします。そうすると、以下のような流れでAIがGoogleカレンダーにアクセスするようになります。
- AIがGoogleカレンダーを開く
- AIがアクセストークンを使用してログインする
- AIが日程の確認を行う(追加はできない)
これで、直接のログイン情報を持たせるリスクがなくなりました。
また、アクセスを止めたい場合には、ログイン情報を変更する必要がなく、発行しておいたアクセストークンを破棄すれば良いだけになります。
アクセストークンって何?
アクセストークンのイメージは、「期間限定・権限制限付きの入場券」です。
Googleカレンダーへアクセスできる期間を設定しておくことで、万が一、トークンが流出しても期間が切れていればアクセスされません。
外部APIとの連携を実装する時に、Bearer TokenやAPIキーを渡すと思いますが、あれもアクセストークンです。
期間が設定されていないAPIキーは、流出した時のリスクが高いですが、度々再発行するという運用が良くないと判断される場合があります。(取り扱うデータの機密性などとの天秤にかけられることが多いですね。)
イメージとしては以下です。
1. Bearer Tokenを使ってAPIリクエストを送信
GET /calendar/events
Authorization: Bearer xxxxxxxxxxxxxxxx...
2. APIのサーバー側でトークンの検証
このAccess Tokenは有効?
↓
calendar.read権限ある?
↓
OK
検証が通れば、カレンダーにアクセスができる。
アクセストークンに必要な「スコープ」
スコープとは、「どこまで許可するか」です。要するに「権限」ですね。
これをアクセストークンに任意に設定するのが、OAuthの良いところでもあります。
つまり、OAuthとは、「誰が、どのアプリに、何を、どこまで許可するか」という概念なのです。
OAuthの代表的な流れ
OAuthは以下のような流れで認可処理が行われるのが一般的です。
1. ユーザーがGoogle Calendar連携を試みる
↓
2. アプリが「GoogleのAuthorization Server」へリダイレクト
↓
3. Googleが「このアプリにCalendarアクセスを許可する」か検証を行う
↓
4. ユーザーがアプリへのカレンダーアクセスを許可する
↓
5. Googleが「Authorization Code」をアプリへ返す
↓
6. アプリがAuthorization CodeをGoogleへ送る
↓
7. Googleがアクセストークンを返す
↓
8. アプリがアクセストークンでCalendar APIを呼ぶ
OAuth と OIDC の違い
OAuthとよく合わせて使われるのが、OIDCです。OIDCは、認可ではなく 認証 です。
簡単に比較すると以下のように整理できます。
| 比較項目 | OAuth 2.0 | OpenID Connect(OIDC) |
|---|---|---|
| 主な目的 | 認可 | 認証 |
| 一言でいうと | 「何をしていい?」 | 「あなたは誰?」 |
| 英語 | Authorization | Authentication |
| 何を委譲する? | APIやデータへのアクセス権限 | ユーザーの本人情報 |
| 主なToken | Access Token | ID Token + Access Token |
| Access Tokenの用途 | APIへアクセスする | APIへアクセスする |
| ID Token | 基本的に登場しない | 登場する |
| ID Tokenの用途 | — | 「誰がログインしたか」をClientに伝える |
| ユーザー情報 | OAuth単体では保証しない |
subなどのユーザー情報を取得できる |
| Scopeの例 |
calendar.read、repoなど |
openid、profile、emailなど |
| ログイン用途 | 本来の用途ではない | ログイン用途に使える |
| 代表的な用途 | Google Calendar連携、GitHub API連携など | Googleログイン、Microsoftログインなど |
| 関係 | ベースとなる仕組み | OAuth 2.0を拡張した認証プロトコル |
ただし、完全に「認証の仕組み」ではなく、「OAuth 2.0の仕組みを利用して「認証」もできるように拡張したもの」という解釈が近いです。
AWSで考える
AWS独自のOAuthがあるわけではないです。OAuthやOIDCがAWSのサービスに実装されているイメージです。(そりゃそうだな。)
AWSの認証・認可のサービスといえば、Cognito だと思います。その中の、User Poolsという機能を使うことで、OIDCのIdentity Providerとして振る舞うことができ、OAuth 2.0のAuthorization Serverとしてアクセストークンなどを発行できるようになります。
例えば、「React, API Gateway, Lambda, DynamoDB」の構成でアプリケーションが実装されているとします。そして、一般ユーザと管理者がログインする想定とします。
この構成に Cognitoを追加すると、認証・認可の実装を行うことができるようになります。前述した、アクセストークンのスコープの定義も行うことが可能です。
また、AWSリソースに対する認証・認可は IAM を使用します。Policyに当たるものが、認可のスコープですね。
まとめ
認証と認可の違いについては理解しておきましょう。
以上