OAuth 2.0 を完全に理解したので図にしてみた

公開日:2019-07-19
最終更新:2019-07-22

あらすじ

今まで OAuth は「認証とか簡単にできてすごいんだなー」程度に思っていました。
しかし仕事でOAuth(に近い仕組み)を実装することになり、雰囲気でOAuthを使うわけにはいかなくなりました
というわけで、理解しようぜOAuth! と意気込んで勉強を始めましたが……単なる OAuth 2.0 を認証に使うと、車が通れるほどのどでかいセキュリティー・ホールができる認証と認可は違うOpenID Connectって

本記事は、OAuth 2.0 初心者に向けた入門記事を目指しています。

対象読者

  • OAuth 2.0 の雰囲気すらつかめてない人
  • OAuth 2.0 の勉強を始めたい人

対象にしない読者

  • OAuth 2.0 の雰囲気のさらに向こうへ進みたい人
  • OAuth 2.0 を整理して理解したい人

おすすめ資料

一番お世話になりました。これが無ければいまだに OAuth 2.0 難民だったと言っても過言じゃないです。
今なら電子版が野口さん一人で買える! お得!

猫も杓子も公式文書。困ったときは公式を見ればとりあえず間違いは無いです。
ただし理解できるかは別問題。まー難しいこと……わからないところはググって情報を補完していくといいかもしれません。

OAuth 2.0について

認証と認可

まずは認証と認可について、この記事では以下のように定義します。

  • 認証 …… 個人や団体等を特定すること
  • 認可 …… 行動やリソースの利用などについて権限を与えること

例えば住民票やマイナンバーカードを見せれば、自分が「誰なのか」を特定する情報を相手に与えることができます。これが認証ですね。
またライブや映画のチケットを見せれば、自分がライブや映画を見る「権限がある」という情報を相手に与えることができます。これが認可です。
この両方の機能を備えているのが運転免許証や保険証になります。例えば運転免許証では、自分が「誰なのか」という証明と運転をする「権限がある」という証明の両方を行うことができます。

OAuth 2.0 の目的

次にOAuth 2.0 の目的について確認します。
OAuth 2.0 の資料で、OAuth 2.0 で解決したい問題について言及されています。

In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner's
credentials. In order to provide third-party applications access to
restricted resources, the resource owner shares its credentials with
the third party. This creates several problems and limitations:

  • Third-party applications are required to store the resource
    owner's credentials for future use, typically a password in
    clear-text.
  • Servers are required to support password authentication, despite
    the security weaknesses inherent in passwords.
  • Third-party applications gain overly broad access to the resource
    owner's protected resources, leaving resource owners without any
    ability to restrict duration or access to a limited subset of
    resources.
  • Resource owners cannot revoke access to an individual third party
    without revoking access to all third parties, and must do so by
    changing the third party's password.
  • Compromise of any third-party application results in compromise of
    the end-user's password and all of the data protected by that
    password.

    OAuth addresses these issues by introducing an authorization layer
    and separating the role of the client from that of the resource
    owner. In OAuth, the client requests access to resources controlled
    by the resource owner and hosted by the resource server, and is
    issued a different set of credentials than those of the resource
    owner.

ここで用語について確認しておきましょう。

  • リソースオーナー(resource owner) …… リソース保持者。例:一般ユーザー
  • リソース(resource) …… サーバーに保持している情報。例:ユーザーの個人情報
  • サーバー(server) …… リソースを保持しているサービス。例:ツイッター
  • クライアント(client) …… サードパーティアプリケーション。例:twicca

これらをもとに上記の英語を雑に翻訳すると、以下の通りになります。

従来ではクライアントがアクセス制限されたリソースを取得するために、リソースオーナーの認証情報を利用していた。そのために、以下の問題が発生していた。

  • クライアントがリソースオーナーのパスワードを平文で保持していた
  • パスワードに起因するセキュリティ脆弱性があるにもかかわらず、サーバーはパスワード認証の対応を求められた
  • リソースオーナーはクライアントに対し、接続可能な期間やアクセスできるリソースを制限することができなかった
  • リソースオーナーは特定のクライアントについてアクセス取り消しをすることができず、パスワード変更による全クライアントのアクセス取り消ししかできなかった
  • 任意のクライントと連携するには、リソースオーナーのパスワードを利用し、全てのデータをそのパスワードで保持することになった

OAuth はリソースオーナーとクライアントの役割を異なる認可層で分離し、クライアントにはリソースオーナーと異なる認証情報を発行することで、これらの問題を解決する。

つまり、「クライアントに対し、リソースオーナーが管理しサーバーに保持されているリソースを安全に渡したい」ということです。
そしてそのための手段として、リソースを保持するサーバーからクライアントに認証情報を発行する手続きを規定しています。

これらをまとめると、OAuth 2.0 の目的は以下の通りです。

  • サーバーがクライアントに対し認証情報を発行する手段を規定する
    • リソースオーナーはクライアントがアクセスできる期間を制限できること
    • リソースオーナーはクライアントがアクセスできるリソースを制限できること
    • リソースオーナーは個別のクライアントに対しアクセス権限の破棄ができること

OAuth 2.0 のフロー例

それではフローを見ていきましょう。

ここではわかりやすいように、各用語に以下の名前をあてはめます。

  • リソースオーナー → ユーザー
  • クライアント → hogeアプリ
  • サーバー → piyoサーバー
  • リソース → piyoリソース

また前提として、以下の条件が必要になります。

  • ユーザーはpiyoサーバーに対する認証情報を持つ
    • ここでは「ユーザーがpiyoアプリにアカウントを持ち、ログインできる」とします
  • ユーザーはプライベートなpiyoリソースをpiyoサーバーに保持している

ユーザーがhogeアプリに対してpiyoリソースを安全に提供したいとき、以下のようなOAuthフローが考えられます。

  1. フローを開始します
  2. hogeアプリはpiyoサーバーに「hugaアプリからのpiyoリソース要求だよ」といった情報を付与してユーザーをリダイレクトさせます
  3. piyoサーバーは要求に従い、まずユーザー認証を要求します(この場合はログイン)
  4. ユーザー認証が確認できた場合、piyoサーバーはユーザーに「hogeアプリにpiyoリソースを提供してもいいですか?」と確認します
  5. ユーザーが許可を出した場合、認可コードを発行し、ユーザーをリダイレクトさせます
  6. 認可コードを受け取ったhogeアプリは、認可コードを利用してpiyoサーバーにアクセストークンリクエストを送ります
  7. piyoサーバーは、hogeアプリから送られた認可コードが正当なものであるか検証します
  8. 認可コードが正当だった場合、piyoサーバーはhogeアプリにアクセストークンを発行します

ここまでが一連の流れですね。
前述した通り、OAuth 2.0 の目的はクライアント(hogeアプリ)に認証情報を発行することなので、アクセストークンの発行により完了します。
hogeアプリはアクセストークンを使うことで、認可された範囲でpiyoリソースを取得することができるようになります。

以上がものすごくおおざっぱな説明です。なんとなくイメージできたでしょうか?
ここで例に出したフローは OAuth 2.0 で定義されている4つのフローのうち、代表的な認可コードフローと呼ばれるものです。

認可サーバーとリソースサーバー

先ほどの例ではサーバーを一つのものとして扱いましたが、一般的には2つの役割ごとに別個のサーバーとして扱われます。
それが認可サーバーリソースサーバーです。
両者について、RFC6749では以下のように定義されています。

  • authorization server
    The server issuing access tokens to the client after successfully
    authenticating the resource owner and obtaining authorization.
  • resource server
    The server hosting the protected resources, capable of accepting
    and responding to protected resource requests using access tokens.

認可サーバーはクライアントへのアクセストークン発行を、リソースサーバーは保護されたリソースの保持(およびアクセストークンを用いたリソースへのリクエスト処理)を担当します。
つまり、先ほどのフローでいうサーバーとは認可サーバーのことを指します。
そして、最終的に得られたアクセストークンを使ってリソースサーバーへアクセスすることによりリソースが得られます。

先ほどの図におけるサーバーを認可サーバーに修正し、またフローの最後にリソースを取得する処理を加えると以下の図になります。

OAuth 2.0 の目的は認証情報発行処理を規定することですが、OAuth 2.0 を利用する人の目的はリソースの安全な受け渡しです。
よって、ここまでがOAuth 2.0 を利用した場合のフローと言ってもいいかもしれません。

最後に、OAuth 2.0 で規定されている用語を使ってフローを書き直しておきましょう。

response_type: 認可サーバーに要求するレスポンス形式。認可コードフローでは`code`固定。  
client_id: クライアントを一意に識別するID。  
code: 認可コード。  
grant_type: 認証情報を発行する処理を判別するための文字列。認可コードフローでは`authorization_code`固定。  
access_token: アクセストークン。これを用いてリソースサーバーに対しリソースアクセス要求を行う。  
token_type: アクセストークンの種類。  

※上記フローでは必要最小限のパラメータしか記載していません。

OAuth 2.0 による課題解決

本記事の前半で、OAuth 2.0 の目的は以下の通りと説明しました。

  • サーバーがクライアントに対し認証情報を発行する手段を規定する
    • リソースオーナーはクライアントがアクセスできる期間を制限できること
    • リソースオーナーはクライアントがアクセスできるリソースを制限できること
    • リソースオーナーは個別のクライアントに対しアクセス権限の破棄ができること

ここで、OAuth 2.0 がこれらを満たすことができるか確認してみましょう。

  • サーバーがクライアントに対し認証情報を発行する手段を規定する

これについては今まで説明してきた通り、OAuth 2.0 で認証情報発行フローを規定しています。OKですね。

  • リソースオーナーはクライアントがアクセスできる期間を制限できること
  • リソースオーナーはクライアントがアクセスできるリソースを制限できること
  • リソースオーナーは個別のクライアントに対しアクセス権限の破棄ができること

クライアントのリソースに対するアクセス権限はアクセストークンによって管理されます。言い換えれば、特定のアクセストークンに対してアクセスの拒否やアクセス権限の破棄を行うことで、そのアクセストークンを持つクライアントからのアクセスを制限することができます。
そして、リソースオーナーにアクセストークン管理機能を提供すれば本条件を満たすことができます。
以上から、これらもOKとみていいでしょう。

すなわち、OAuth 2.0 を用いることにより、ただIDとパスワードをクライアントに渡すよりもはるかに安全なリソース管理が行えるようになります。

おわりに

OAuth 2.0 の学習を始める人にとってわかりやすい記事になっていれば幸いです。
ひとまず本記事はここで終わりますが、今後より詳しいセキュリティの問題等の記事を書いていこうと思います。

ちなみに、本記事でリソースオーナー - クライアント間の認証について全く触れていないことにお気づきでしょうか?
OAuth 2.0 の規定においても上記認証についてはほとんど触れていません(stateが上記認証情報に該当するかもしれませんが……)。
OAuth 2.0 はあくまでリソースオーナー → クライアントの認可処理とクライアント - サーバー間の認証に関するものであるため、リソースオーナー - クライアント間の認証については(もっと言うならリソースオーナー - サーバー間の認証についても)対象外であると私は認識しています。
そこで出てくるのがOpenID Connectですが、これについてはまた別記事にしたいと思います。

参考資料

雰囲気でOAuth2.0を使っているエンジニアがOAuth2.0を整理して理解できる本
認証と認可
OAuth 2.0

記事が少しでもいいなと思ったらクラップを送ってみよう!
44
+1
だらだら更新していきたい技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする