🎮

OAuthの言葉周りを整理する

2022/06/18に公開

OAuthの仕組みとToken認証周りの言葉はいつまで経ってもはっきり理解できないものの一つでした。

しかし最近ようやく理解できるようになってきたのでとりあえずそれぞれの言葉の指すものや定義をここで整理してみようと思います。


リフレッシュトークン

リフレッシュトークンとは

アクセストークンの有効期限が切れたときに、認可サーバーにアクセストークンの更新リクエスト認証をするためのトークン。

OAuth自体はリフレッシュトークンがなくとも実装できるが、リフレッシュトークンはOAuthをより便利にするためのもの。

一般的に有効期限は長い。

ないとどうなるのか

アクセストークンの期限が切れたらその度にSNS認証のあのログイン画面に飛ばされてメアドとパスワードの入力が必要になる。

セキュリティに関すること

有効期限が長くても安全性に問題がないと考えられる理由としては、アクセストークンの期限切れ時にしかネットワークにさらされないから。

各個人がこれをCookieやLocalstorageで保存することに関する安全性は、また別の問題である。


アクセストークン

アクセストークンとは

認可サーバーから発行されるトークン。

一般的に短命な有効期限が定められている。

2種類のアクセストークン

  1. シンプルな文字列でなにも内容を含めないもの

  2. JSON形式などで表現される何かしらの情報を含むもの

    アクセストークンごとの権限の管理ができる。(OAuthのメリットの1つ)この機能により、webサービス提供者が行える範囲も限られ認可サーバーを持つ会社のセキュリティが上がる。

特徴

webサービス提供者は多くの場合、GoogleやFacebookやtwitterなどのアクセストークンを利用した認証を実装することになる。その際、認証機能を実装することなくリクエストヘッダ内にあるアクセストークンの有効期限を見るだけでいいため、実装の手間が減る。

セキュリティに関すること

有効期限の短いためネットワーク上に晒されても問題があまりない。

リフレッシュトークンと同じく、これをどのように保管するかというのはまた別の問題。

アクセストークンは盗まれると、リダイレクトURI発行時にパラメータを置き変えることで不正アクセスを行うことができてしまう(カット&ペーストアタック)。これを防ぐために考えられたのが後述するOpenID Connect認可コードフロー。アクセストークンの発行元を検証することでその対策は可能なため、やり方は色々ある。


認可コード

認可コードとは

アクセストークンの発行を要求する際に利用するランダムな文字列。

認可コードフローで利用される概念。これを使うとアクセストークンの置き換えによる不正アクセスができないようになる。

一般的に有効期限は数分単位と短命。

特徴

アクセストークンを安全に発行するためのフローで使われる。


auth2.0

auth2.0とは?
権限の認可を行うための標準プロトコル。

特徴

  • アクセストークン発行者から見て

    auth2.0の使用にしたがって発行されたアクセストークンでは、発行した元は使用できる機能を制限できる。(ID・パスワード認証ではできない)

  • アクセストークン再利用者(webサービス開発者)から見て

    アクセストークンを再利用して自分のサービスを提供する外部の開発者は、認証機能実装の手間が省ける。

    悪意のある攻撃がアクセストークンの権限内でしかできない。

  • ユーザーから見て

    ログインのためのパスワード入力をする機会が減り、UXが向上する。

注意点

OAuth単体ではセキュリティ不足。(HTTPのように)

取得したアクセストークンをどう扱うかまではこのプロトコルの範囲外の話。


openID connect

openID connectとは?

OAuth2.0プロトコルを拡張したもの

特徴

OAuth 2.0 + Identity Layer = openID connect

OpenIDconnectはOpenID 1.0 → OpenID 2.0 の系譜から生まれたもの。
OpenID 2.0はID情報の共有という面でUXの向上に成果を上げた。しかし、開発者の目線からするとAPI利用には使えなかったりといった痛みがあった。これを改善した。

OpenIDconnectはJWTを使った認証方式を標準としており、OpenIDConnectではこれをIDトークンと読んでいる。

OpenIDConnectとOAuthでは同じ機能を持つものでも呼び方が異なることがあり、理解しにくいポイントとなっている。

  • 認可サーバー -> OpenID Provider(OP) / Identity Provider(IdP)

[参考記事](https://www.buildinsider.net/enterprise/openid/connect)

使われている例
GitHubActionとAWSなどのクラウドリソースとの認証。最近サポートされた機能。
AWSのクレデンシャルをGitHubに保存して、それを使った認証が基本だったが、OIDCを使うことでクレデンシャルの管理が不要になる。
認証の手順

  1. OIDCに使用するIDトークン(ユーザー情報を含んだアクセストークン)をGitHubの認可サーバーから生成。
  2. awsに送る
  3. awsからGitHubの認可サーバーにトークンの検証を行う。

Memo

世代的にopenID2.0での認証がイメージしづらい。

jwt・jws・jweの詳しい説明はこちら


カット&ペーストアタック

カット&ペーストアタックとは

サービスプロバイダーが悪意のある人だった場合、アクセストークンの発行リクエストが正しい送信者からのものか判断できないために成功してしまう攻撃手法。

oauth2.0では認証機能は保証されていないため、アクセストークン発行リクエストが善意のものかどうかを判断する必要がある。(認可コードフローやopenID connectを使う)

Memo

FacebookにはopenID connectの元になった独自のsigned requestというAPIの他に、デフォルトのclient side flow といったアクセストークン発行APIもあるが、こちらではカット&ペーストアタックに対抗できない。


認可コードフロー

認可コードフローとは

OAuth認可・トークン認証方式の一種

特徴

最も一般的なOAuthフロー。

アクセストークンの発行のために認可コードが発行される。
それを検証して有効な場合にアクセストークンは発行され、認可サーバーにユーザー情報と紐づいた状態で保存される。

発行されるアクセストークンにはリソース制限をかけられる。これは事前にwebサービス開発者の申請によって発行されるクレデンシャルを用いているため。


クライアントクレデンシャルフロー

クライアントクレデンシャルフローとは?

OAuth認可・トークン認証方式の一種

特徴

認可コードフローでリソースの制限リダイレクト先URIの生成に使用されていたクレデンシャルの用途が変わったもの。このフローではアクセストークンを直接発行するために使われる。

ユースケース

バッチ処理など複数ユーザーがクレデンシャルに関わる必要がなく開発者のみにリソースを使用できる権限があればいい時など。

注意点

クレデンシャルでできることの権限が大きいため複数ユーザーに配布してはいけない。


リソースオーナーパスワードクレデンシャルズフロー

リソースオーナーパスワードクレデンシャルズフローとは?

OAuth認可・トークン認証方式の一種

特徴

ID・パスワード認証と後方互換性を持たせた状態でトークン認証が実装できるように考えられたもの。ID・パスワード認証のときは認可・リソースサーバーにID・パスワードを送信していた設計を変えずにアクセストークンを取得するフローを組み合わせて認証が行われるように設計された。

ユースケース

ID・パスワード認証を残したままトークン認証に切り替えたい場合など。

非推奨。

注意点

OAuthのメリットである、認可・リソースサーバーへのroleが制限されるというメリットが失われているため非推奨。(悪意のある開発者からの攻撃範囲を限定できない)


IDaasを使ったOAuthフロー

IDaasとは?

Identity as a Serviceの略

Okta・Azure AD・OneLogin・Trust Login・Auth0 などなど。

特徴

IDaasは認可サーバーとしての役割を担う。

そうなると認可サーバーとリソースサーバーが分かれることになり、リソースサーバーでは正しい送信者かどうかの検証が必要になる。

検証方法としては、JWTを利用した公開鍵暗号方式でのアクセストークンの検証が行われる。

アクセストークン発行時、認可サーバーにアクセストークンを保存するという処理が不要になる。


参考記事

https://tech-lab.sios.jp/archives/25470

Discussion