目次


OAuthとは

OAuth(オーオース)とは、アクセス権限の認可を行うためのオープン標準プロトコルです。認可とは、第三者のアプリケーションに、自分のアカウントを用いたWebサービスAPIへのアクセス権限を委譲することを言います。

主にWebサービス同士を連携させて、便利に利用しやすくするための仕組みとして用いられています。OAuthを利用することで、例えばX(旧Twitter)とFacebookを連携させて、Xへ投稿した同じ内容を自動的にFacebookへも投稿させるといったことができます。

OAuthの作成が始まった2007年ごろ、当時はマッシュアップによるWebサービス連携が増えてきた一方で、デジタルアイデンティティの共有が問題となってきていました。

Webサービス連携にあたって一番簡単な実装手段は、Webサービスの認証情報であるID、パスワードなどを、連携したい別のWebサービスでも共有し、自由にアクセスできる状態にすることです。

しかし、連携のためとはいえ、異なるWebサービス間でIDパスワードを共有し、個人情報へも自由にフルアクセスできるような状況は好ましくありません。認証情報を濫用することなく、必要なWebサービスAPIへのアクセスのみを認可する手段があればベターと言えるでしょう。

そこで、XなどのWebサービス開発者が集い、APIアクセス権限委譲の方法について議論しました。しかし、「そのようなAPIアクセス権限委譲についてのオープン標準はまだ存在しない」という結論に至ったのです。

「ないなら作るしかない」と、当時の開発者たちはAPIアクセス権限委譲のオープンプロトコルを作成するためにOAuthインターネットコミュニティを立ち上げ仕様策定を進め、その結果として2007年10月に最初のOAuth Core 1.0が登場しました。

2012年には実装を簡略化して機能強化を図ったOAuth 2.0が登場し、現在はOAuth 2.0がオープン標準として用いられています。今回の記事では、基本的にOAuth 2.0を対象とした解説をしていきます。

OpenID(OpenID Authentication)との違い

OAuthと混同しがちなプロトコルに、OpenID Authenticationがあります。OpenID Authenticationはユーザー認証に特化したプロトコルで、複数のWebサービスに対するユーザー認証をひとつのIDに集約させる、シングルサインオンといったサービスを可能にします。

OpenID Authenticationでは、「OpenIDプロバイダー」というOpenID認証サーバーでユーザー認証を行います。OpenID対応のWebサービスへユーザーがサインインしようとすると、ユーザーはOpenID認証サーバーにリダイレクトされ、そこでユーザー認証を求められます。

ユーザー認証に成功したら、認証結果とともにユーザーを本来のWebサービスへリダイレクトすることで、そのままWebサービスが利用可能となります。このサーバー間のユーザー認証の一連のやり取りを標準化したものが、OpenID Authenticationです。

OpenID Authenticationは、OAuthより前に登場していたプロトコルです。Webサービスの開発者たちは最初、OpenID Authenticationを用いてAPIアクセス権限委譲を実現できないかとも考えていましたが、結局OpenID Authenticationでの実現は困難ということで、OAuthの作成につながりました。

【関連記事】

「認証」と「認可」の違い

OpenID Authenticationはユーザー認証に関するプロトコルで、OAuthはWebサービスAPIのアクセス権限の認可に関するプロトコルです。両者の違いを知るには「認証」と「認可」の違いを意識しておく必要があるでしょう。

認証とは「相手が何者であるか確認する」ことを意味します。一方で認可とは「指定した機能を使う権限を与える」という意味を持ちます。意味は明らかに異なりますが、一般に「Webサービスの認証を通るとWebサービスへのアクセス権限が付与される」という図式が成り立つため、認証と認可はセットで同一のものと捉えられていても不思議ではありません。

両者を厳密に分離した場合、認証は相手を確認するところまでで終了し、認可はアクセス権限を持つものがどこの誰かということは関知せず、アクセス権限を持っていたらアクセス可能になるという考え方になります。

結果として、ユーザー認証に特化したOpenID Authenticationはアクセス権限の認可に関する機能がないため、Webサービス連携には不適合となります。一方でアクセス権限の認可に特化したOAuthは、アクセス権限という「鍵」の有無を認証の代わりとしてWebサービスAPIにアクセスできる仕様なので、連携相手の第三者アプリケーションにIDパスワードといった認証情報を持たせる必要がなく、Webサービス連携を安全に構築できるという利点にもなるわけです。

OAuthの仕組み

OAuthは一般的なIDパスワード認証ではなく、トークンベースの認証を利用したプロトコルです。

OAuthの仕組みを説明するために、ユーザーデータを管理しWebサービスを提供する「リソースサーバー」、Webサービスと連携したい「クライアントアプリ」、OAuthのトークンを発行する「認可サーバー」という最小限の構成で考えてみましょう。

リソースサーバーには要求に応じてユーザーデータのやり取りを行う窓口としてAPIが用意されており、クライアントアプリなどの外部から「○○のデータをください」といった要求がAPIにきたら、該当するユーザーデータを渡してくれます。

ただ、すべての要求に応えていたら悪意を持つ第三者にユーザーデータが漏出してしまうため、APIを悪意の第三者から守る仕組みが必要です。

そこでOAuthでは、APIを守る仕組みにアクセストークンを利用しています。連携させたいクライアントアプリにはあらかじめアクセストークンを持たせておき、そのアクセストークンがリソースサーバーのユーザーデータにアクセスできる権限を持つ証になります。このクライアントアプリにあらかじめアクセストークンを発行する係を担うのが、認可サーバーです。

クライアントアプリはリソースサーバーのAPIへデータを要求する際、所持しているアクセストークンも一緒に提示します。リソースサーバー側ではアクセストークンの内容を検証し、クライアントアプリが本当にアクセス権限を持っているか確認します。アクセス権限が正しいものであれば、あらためてデータをクライアントアプリへ送信します。

この一連の要求と応答の仕組みをOAuthでは標準化しています。

OAuth認可までの流れ・仕組み

ここでは、OAuth認可でクライアントアプリにWebサービスのアクセストークンが発行されるまでの流れを追って解説していきます。

アクセストークンを発行し、Webサービス連携できるまでの流れ

クライアントアプリにWebサービスのアクセストークンを発行し、Webサービス連携を利用できるまでの流れはおおよそ以下のようになります。

1.認可サーバーに連携申請をする

クライアントアプリのシステム管理者が、Webサービスの認可サーバーに対し、クライアントアプリとの連携が可能になるよう申請します。その際、クライアントアプリから利用したい機能(閲覧や投稿など)も併せて申請します。

申請を受けた認可サーバー側では、クライアントアプリに対してクライアントIDとクライアントシークレットというユニークな文字列を生成して割り当て、申請のあった利用したい機能と併せてデータベースに登録します。

これで同クライアントアプリからの連携を受けられるようになります。この作業はクライアントアプリに連携機能を実装した際、最初に1回だけ行う作業です。

2.ユーザーがクライアントアプリに連携を要求する

クライアントアプリ使用中のユーザーがアプリに対し連携要求の操作を行うと、認可サーバーの認可エンドポイントへリダイレクトします。リダイレクト時にはクエリパラメータにクライアントIDを付与し、どのクライアントアプリから連携を要求しているかも同時に知らせます。

3.アプリへのアクセス権限を認可する

認可サーバー側では認可同意画面を生成し「アプリはこのような権限を求めています。権限を承認しますか?」といった確認を求めてきます。ユーザーはWebサービスのIDパスワードを入力してユーザー認証を行い、権限の承認を行います。この一連の手続きでアクセス権限の認可を与えたことになります。

4.認可コードを付与する

認可を得た認可サーバーは、クライアントアプリのURLへリダイレクトして戻します。その際、有効期限が10分間ほどの極端に短く、1回しか使えない認可コード(ランダムな文字列)を生成し、クライアントアプリURLのクエリパラメータに付与して送信します。

5.認可コードをアクセストークンに交換する

クエリパラメータとして認可コードを受け取ったクライアントアプリは、すぐさま認可コードを認可サーバーのトークンエンドポイントへ送り返します。有効期限内の認可コードを確認した認可サーバーは、アクセストークン(ランダムな文字列)を生成し、クライアントアプリに発行します。

6.アクセストークンを用いたサービス利用する

クライアントアプリは発行されたアクセストークンを保存し、Webサービスを利用する時は、WebサービスのリソースサーバーAPIへアクセストークンと併せて利用する機能をリクエストします。

7.リソースサーバーでリクエストを実行する

リソースサーバー側では発行したアクセストークンとユーザー名やアクセス権限がデータベースで紐付けされており、送られてきたアクセストークンに一致するユーザーからのリクエストとしてサービスを提供します。

以上が、OAuthを用いたWebサービス連携の大まかな流れとなります。

アクセストークン取得方法として定義されている4通りのフロー

OAuthでは、さまざまなシチュエーションを想定して、アクセストークンの取得方法に4通りのフローを定義しています。定義されている4つのフローは以下のとおりです。

  1. 認可コードフロー
  2. インプリシットフロー
  3. クライアント・クレデンシャルズフロー
  4. リソースオーナー・パスワード・クレデンシャルズフロー

「認可コードフロー」は、アクセストークンの発行に先立って、認可コードの発行というワンクッションを挟む方法です。先ほどのWebサービス連携までの流れで説明しているのが認可コードフローです。

なぜこのような一手間をかけるのかというと、リダイレクトの際にWebブラウザのアドレスバーに表示されるクエリパラメータは、さまざまな手段で不正に読み出される危険性があるからです。

なので、不正に読まれたとしても、ダメージの少ない認可コードをリダイレクトの際にやり取りし、肝心のアクセストークンはより安全な方法でダウンロードする仕組みになっています。手間はかかりますが、安全性の高い方法です。

「インプリシットフロー」は、認可コードフローの説明で危険性が高いとしたリダイレクトURLのクエリパラメータに直接アクセストークンを付与して発行する方法です。認可コードという一手間を省けるので実装は簡単ですが、セキュリティリスクが高く、非推奨とされる方法です。ただし、ネイティブアプリケーションなどWebブラウザを介したOAuth認可が利用できない場合は、仕方なく使わなければならないケースもあります。

「クライアント・クレデンシャルズフロー」は、ユーザー不介入のアクセストークン取得手法です。サーバーのバックエンドシステム同士がWebサービス連携する際や、バッチ処理でWebサービス連携を利用する際に用いられます。アクセストークン取得の認証にはクライアントIDとクライアントシークレットを用います。クライアントIDとクライアントシークレットさえしっかり管理しておけば高セキュリティを保てるのが特徴です。

「リソースオーナー・パスワード・クレデンシャルズフロー」は、認可サーバーが用意した権限承認画面でIDパスワードを入力するのではなく、クライアントアプリにIDパスワードを直接登録し、あとはユーザーの同意なくクライアントアプリが勝手にIDパスワードを利用して、アクセストークンを取得する方法です。ユーザーの手間が少なく実装も簡単な方法ですが、IDパスワードの直接登録は全権限委譲に等しく、セキュリティリスクがとても高いため、使用は非推奨となっています。

アクセストークン有効期限切れで活躍するリフレッシュトークン

OAuthのセキュリティを担保している特徴のひとつに、アクセストークンの有効期限が約1時間と短いことが挙げられます。有効期限の短いアクセストークンであれば、万一盗聴されたとしても、実害を低く抑えられる可能性が高いです。

一方で、認可サーバーから頻繁にアクセストークンを再発行してもらう必要性が生じます。とはいえ、再発行のたびにユーザーがIDパスワードを入力して権限の認可を行わなければならないのかというと、そうはなっていません。

実はアクセストークンの再発行にはリフレッシュトークンという仕組みが用意されており、最初のアクセストークン発行の際にリフレッシュトークンも同時に発行されて、クライアントアプリが記憶しています。アクセストークンの有効期限が切れると、クライアントアプリは自動的にリフレッシュトークンを利用したアクセストークンの再発行を行います。

リフレッシュトークンの有効期限はさまざまですが、数週間~数か月が一般的で、その間ユーザーがアクセストークンの再発行を気に留める必要はありません。リフレッシュトークンの有効期限が切れた時に、再びアクセス権限の認可を行えば良いのです。

認可サーバーとリソースサーバーが別サービスの場合

先ほどのWebサービス連携の流れの解説では、認可サーバーとリソースサーバーが同一サービスだった場合について取り扱っていました。両者が同一サービスであれば、アクセストークンに紐付けされたユーザーIDやアクセス権限のデータベースをリソースサーバー側からも参照できるので、アクセストークンから該当ユーザーを割り出してサービスを提供することも簡単です。大手のSNSプロバイダーならば、このように認可サーバーとリソースサーバーを一緒に運営していることも珍しくありません。

一方で、認可サーバーとリソースサーバーを別々に運用しているケースも珍しくありません。この場合、リソースサーバーが認可サーバーのデータベースを覗くことはできないので、提示されたアクセストークンが正規のものか、どのユーザーからの要求なのかを別の方法で確かめる必要があります。その方法をいくつか紹介しましょう。

・アクセストークンは識別子型か、内包型か

OAuthで用いるアクセストークンの種類は、識別子型と内包型に大別できます。識別子型は一意の文字列で構成されたアクセストークンで、それに紐付く情報が認可サーバーのデータベース内に保存されています。アクセストークンを元にデータベースにアクセスすることで、ユーザー名やクライアントIDなどの情報を引き出せます。認可サーバーとリソースサーバーが別々の場合、識別子型のアクセストークンは基本的に使えません。

一方の内包型は、ユーザー名やアクセス権限などの必要なデータを、トークン内にすべて保存しているアクセストークンです。アクセストークン単体で役目を果たせるので、認可サーバーとリソースサーバーが別々でも問題ありません。内包型のフォーマットにはJWT(JSON Web Token)が広く用いられています。JWTはヘッダー、ペイロード、署名をそれぞれBase64URLエンコードしたものを.(ピリオド)でつないだ文字列で構成されるフォーマットです。

・電子署名でアクセストークンの改ざんを検証

認可サーバーとリソースサーバーが別々の場合、認可サーバーで発行されたあとにアクセストークンに改ざんが加えられていないかチェックする必要があります。チェック方法として有効なのは電子署名検証で、認可サーバーで入手できる公開鍵を用いて、アクセストークンの電子署名を検証します。改ざんが認められなければ、アクセストークンとして利用できます。

・確実な検証を期待できるイントロスペクションAPI

アクセストークンの有効性を検証する確実な方法のひとつとして、イントロスペクションAPIの利用があります。これは認可サーバーが提供するアクセストークン検証用のAPIで、リソースサーバーからアクセストークンの情報を受け取り、その検証結果が出るとアクセストークンの情報を返すAPIです。アクセストークンを発行した認証サーバー自身が検証を行うので、最も確実な方法のひとつに挙げられます。

【関連記事】

【関連記事】

OAuthを使うメリット

OAuthはインターネット上のサービス間で安全にリソースへのアクセス権を委譲することのできるオープン標準プロトコルです。ここではOAuthを利用するメリットをいくつか紹介していきます。

・クライアントアプリへ自分のリソースへのアクセス権限を安全に委譲できる

OAuthの代表的な用途のひとつに、自分のリソース(写真やクラウドストレージなど)へのアクセス権限をクライアントアプリへ安全に委譲できることが挙げられます。クラウドストレージのデータへアプリケーションから直接アクセスできるようになると、作業も捗ります。

・パスワードの使用を極力避けてセキュリティ向上

OAuthでは基本的にクライアントアプリにパスワードを入力することはありません。また、IDパスワードの入力も、最初の認可同意画面で一度行えば数か月単位で連携が保たれるため、セキュリティリスクの低減にもつながります。

・アクセス権限の範囲(スコープ)は最小限でセキュリティ向上

一般的にWebサービス連携では、必要最小限の機能に絞ってアクセス権限の認可を得ます。仮になりすましの被害にあっても、アクセス権限を絞っていればリスクは最小限に抑えられるでしょう。

・短期間のみ有効なアクセストークンが不正アクセスを防止

アクセストークンは短期間のみ有効であり定期的に更新されるため、不正アクセスを防止できます。

・標準化されたプロトコル

OAuthは標準化されたフレームワークであるため、開発者は実装するための複雑なコードを書く必要がありません。多くのライブラリやフレームワークが利用可能であり、OAuth の実装をさらに簡素化します。

【関連記事】

OAuthを使うデメリット

OAuthは便利で広く利用されているアクセス権限委譲のオープン標準プロトコルですが、利用の際には気を付けなければならないデメリットもあります。利用する上での注意点としていくつか紹介しておきましょう。

・なりすまし不正アクセスの被害リスク

OAuthはその仕様上、特にインプリシットフローを用いてユーザー認証を行っているサービスでは、なりすましで不正アクセスの被害にあう可能性がゼロではありません。これはインプリシットフローがブラウザに直接アクセストークンを渡すことから生じる脆弱性です。「トークン置き換え攻撃」と呼ばれ、条件を満たせば誰に気づかれることもなく別人としてアプリにサインインすることができてしまいます。

・フィッシング詐欺の被害リスク

悪意あるWebサイトやアプリによる定番攻撃のひとつが、偽のアクセス権限認可同意画面を表示してIDパスワードを盗み取ろうとする、フィッシング詐欺です。画面を表示した後で見破るのは難しいかもしれませんが、メールやメッセージで送られてきたURLは絶対触らないなどの自衛が必要になります。

・正規アプリに見せかけた同意フィッシング攻撃

OAuth対応アプリで昨今特に問題となっているのが、正規アプリに見せかけて過剰に広範囲なアクセス権限の認可を求める、悪意あるアプリの「同意フィッシング攻撃」です。認可同意画面で特に気に留めることなく同意をしてしまうと、アカウントの個人情報のかなり深い部分までアクセスする権限を与えてしまう危険もあります。

・OAuthをユーザー認証代わりにするリスク

OAuthはアクセス権限の認可に特化したプロトコルです。ユーザー認証の真似事のようなことはできますが、使い方によってはなりすまし不正アクセスが可能なことを考えると、大きなセキュリティリスクと言えます。

このようなユーザー認証を重視する用途では、OpenID Connectの利用が広まってきています。OpenID ConnectはOAuth 2.0を拡張したプロトコルで、従来のOAuthにはなかった「誰の」という情報を扱うIDトークンが追加されています。

IDトークンにはユーザーの認証情報とプロフィール情報が含まれており、リソースサーバー側はIDトークンを検証することで、正しく認証されているユーザーからのリクエストだと確認できるようになりました。これにより、なりすまし被害のリスクも低減しています。よく見かける「Googleでサインイン」などもOpenID Connectで実装されている機能です。

【関連記事】

OAuthはWebサービスにおいて必要不可欠な技術

OAuthはWebサービスの連携を安全に実装するためのオープン標準プロトコルです。さまざまなWebサービスを利用している現在において、必要不可欠な技術といえるでしょう。すでに広く活用されており、多くの人が知らず知らずのうちにふだんからOAuthのお世話になっているはずです。

OAuthと、それを拡張したOpenID Connectは適材適所で使い分けられており、現在のWebサービスの利便性はさらに大きく向上しました。Webサービス連携の認可同意画面を見かける機会もより多くなってきていると思います。その裏ではこのような技術が利用されているということに思いを馳せると同時に、認可同意画面ではセキュリティリスクのことも常に想像し、条件をよくチェックしてから同意するように心掛けましょう。