OAuth2の概要
序章
OAuth 2 は、Facebook、GitHub、DigitalOceanなどのアプリケーションがHTTPサービス上のユーザーアカウントへの制限付きアクセスを取得できるようにする認証フレームワークです。 これは、ユーザー認証をユーザーアカウントをホストするサービスに委任し、サードパーティアプリケーションにそのユーザーアカウントへのアクセスを許可することで機能します。 OAuth 2は、モバイルデバイスだけでなく、Webおよびデスクトップアプリケーションの承認フローを提供します。
この情報ガイドは、アプリケーション開発者を対象としており、OAuth 2の役割、承認付与の種類、使用例、およびフローの概要を提供します。
OAuthの役割
OAuthは4つの役割を定義します。
- リソース所有者:リソース所有者は、アプリケーションにアカウントへのアクセスを許可するユーザーです。 ユーザーのアカウントへのアプリケーションのアクセスは、付与された承認の範囲に制限されます(例: 読み取りまたは書き込みアクセス)
- クライアント:クライアントは、ユーザーのアカウントにアクセスしたいアプリケーションです。 その前に、ユーザーによって承認されている必要があり、承認はAPIによって検証されている必要があります。
- リソースサーバー:リソースサーバーは、保護されたユーザーアカウントをホストします。
- 承認サーバー:承認サーバーはユーザーのIDを確認してから、アプリケーションにアクセストークンを発行します。
アプリケーション開発者の観点からは、サービスのAPIはリソースと承認サーバーの両方の役割を果たします。 これらの両方の役割を組み合わせて、ServiceまたはAPIの役割と呼びます。
抽象プロトコルフロー
OAuthの役割が何であるかがわかったので、それらが一般的にどのように相互作用するかを示す図を見てみましょう。
図の手順の詳細は次のとおりです。
- アプリケーションは、ユーザーからサービスリソースにアクセスするための承認を要求します
- ユーザーがリクエストを承認した場合、アプリケーションは承認付与を受け取ります
- アプリケーションは、承認サーバー(API)に、自身のIDの認証と承認付与を提示することにより、アクセストークンを要求します。
- アプリケーションIDが認証され、承認付与が有効な場合、承認サーバー(API)はアプリケーションにアクセストークンを発行します。 承認が完了しました。
- アプリケーションはリソースサーバー(API)にリソースを要求し、認証用のアクセストークンを提示します
- アクセストークンが有効な場合、リソースサーバー(API)はリソースをアプリケーションに提供します
このプロセスの実際のフローは、使用している許可付与のタイプによって異なりますが、これが一般的な考え方です。 さまざまな助成金の種類については、後のセクションで説明します。
アプリケーション登録
アプリケーションでOAuthを使用する前に、アプリケーションをサービスに登録する必要があります。 これは、サービスのWebサイトのdeveloperまたはAPI 部分にある登録フォームを介して行われます。ここで、次の情報(およびおそらくアプリケーションの詳細)を提供します。
- アプリケーション名
- アプリケーションWebサイト
- URIまたはコールバックURLをリダイレクトする
リダイレクトURIは、ユーザーがアプリケーションを承認(または拒否)した後にサービスがユーザーをリダイレクトする場所であり、したがって、承認コードまたはアクセストークンを処理するアプリケーションの部分です。
クライアントIDとクライアントシークレット
アプリケーションが登録されると、サービスはクライアント資格情報をクライアント識別子およびクライアントシークレットの形式で発行します。 クライアントIDは、アプリケーションを識別するためにサービスAPIによって使用される公開された文字列であり、ユーザーに提示される認証URLを構築するためにも使用されます。 クライアントシークレットは、アプリケーションがユーザーのアカウントへのアクセスを要求したときに、サービスAPIに対してアプリケーションのIDを認証するために使用され、アプリケーションとAPIの間で非公開にする必要があります。
認可付与
前に概説した抽象プロトコルフローでは、最初の4つのステップは、許可付与とアクセストークンの取得を対象としています。 承認付与タイプは、アプリケーションが承認を要求するために使用する方法と、APIでサポートされている付与タイプによって異なります。 OAuth 2は、3つの主要な付与タイプを定義し、それぞれがさまざまな場合に役立ちます。
- 認証コード:サーバー側アプリケーションで使用
- クライアントクレデンシャル:APIアクセス権を持つアプリケーションで使用されます
- デバイスコード:ブラウザがない、または入力が制限されているデバイスに使用されます
警告:OAuthフレームワークは、 ImplicitFlowタイプとPasswordGrantタイプの2つの追加の付与タイプを指定します。 ただし、これらの付与タイプはどちらも安全でないと見なされているため、使用は推奨されていません。
次のセクションでは、付与タイプ、その使用例、およびフローについて詳しく説明します。
付与タイプ:認証コード
認証コード付与タイプは、ソースコードが公開されていないサーバー側アプリケーション、およびクライアントシークレットの機密性に最適化されているため、最も一般的に使用されます。維持することができます。 これはリダイレクトベースのフローです。つまり、アプリケーションは user-agent (つまり、 ユーザーのWebブラウザー)およびユーザーエージェントを介してルーティングされるAPI認証コードを受信します。
次に、認証コードフローについて説明します。
ステップ1—認証コードリンク
まず、ユーザーには次のような認証コードのリンクが与えられます。
https://cloud.digitalocean.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
このサンプルリンクのコンポーネントの説明は次のとおりです。
- https://cloud.digitalocean.com/v1/oauth/authorize :API認証エンドポイント
- client_id = client_id :アプリケーションのクライアントID (APIがアプリケーションを識別する方法)
- redirect_uri = CALLBACK_URL :認証コードが付与された後、サービスがユーザーエージェントをリダイレクトします
- response_type = code :アプリケーションが認証コードの付与を要求していることを指定します
- scope = read :アプリケーションが要求しているアクセスのレベルを指定します
ステップ2—ユーザーがアプリケーションを承認する
ユーザーがリンクをクリックするときは、最初にサービスにログインしてIDを認証する必要があります(既にログインしている場合を除く)。 次に、サービスによって、アカウントへのアプリケーションアクセスを承認または拒否するように求められます。 アプリケーションプロンプトの承認の例を次に示します。
この特定のスクリーンショットはDigitalOceanの認証画面であり、 DropletbookAppが[email protected]
のアカウントへのreadアクセスの認証を要求していることを示しています。
ステップ3—アプリケーションが認証コードを受け取る
ユーザーがアプリケーションの承認をクリックすると、サービスはユーザーエージェントを承認コードとともにクライアント登録時に指定されたアプリケーションリダイレクトURIにリダイレクトします。 リダイレクトは次のようになります(アプリケーションがdropletbook.com
であると想定)。
https://dropletbook.com/callback?code=AUTHORIZATION_CODE
ステップ4—アプリケーションがアクセストークンを要求する
アプリケーションは、クライアントシークレットを含む認証の詳細とともに認証コードをAPIトークンエンドポイントに渡すことにより、APIからアクセストークンを要求します。 DigitalOceanのトークンエンドポイントへのPOST
リクエストの例を次に示します。
https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
ステップ5—アプリケーションがアクセストークンを受信する
承認が有効な場合、APIはアクセストークン(およびオプションで更新トークン)を含む応答をアプリケーションに送信します。 全体の応答は次のようになります。
{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{"name":"Mark E. Mark","email":"[email protected]"}}
これで、アプリケーションが承認されました。 トークンを使用して、トークンが期限切れになるか取り消されるまで、アクセス範囲に限定されたサービスAPIを介してユーザーのアカウントにアクセスする場合があります。 更新トークンが発行された場合、元のトークンの有効期限が切れていると、それを使用して新しいアクセストークンを要求できます。
コード交換用のプルーフキーに関する注意
パブリッククライアントが認証コード付与タイプを使用している場合、認証コードが傍受される可能性があります。 コード交換用のプルーフキー(または PKCE 、「ピクシー」のように発音)は、この種の攻撃を軽減するのに役立つ認証コードフローの拡張機能です。
PKCE拡張機能には、クライアントがすべての認証要求に対して秘密鍵(コードベリファイアと呼ばれる)を作成および記録することが含まれます。 次に、クライアントはコードベリファイアをコードチャレンジに変換し、コードベリファイア、コードチャレンジ、および変換メソッドを同じ承認リクエストの承認エンドポイントに送信します。
承認エンドポイントは、コードチャレンジと変換方法を記録し、前に概説したように承認コードで応答します。 次に、クライアントは、最初に生成したコードベリファイアを含むアクセストークン要求を送信します。
コードベリファイアを受信した後、認証サーバーは、クライアントによって最初に共有された変換方法を使用して、コードベリファイアをコードチャレンジに変換します。 クライアントによって送信されたコードベリファイアから派生したコードチャレンジが、認証サーバーによって最初に記録されたものと一致しない場合、認証サーバーはクライアントアクセスを拒否します。
セキュリティを向上させるために、すべてのクライアントでPKCE拡張機能を使用することをお勧めします。
付与タイプ:クライアント資格情報
クライアント資格情報付与タイプは、アプリケーションに独自のサービスアカウントにアクセスする方法を提供します。 これが役立つ場合の例としては、アプリケーションが登録済みの説明を更新したり、URIをリダイレクトしたり、APIを介してサービスアカウントに保存されている他のデータにアクセスしたりする場合があります。
クライアントクレデンシャルフロー
アプリケーションは、クレデンシャル、クライアントID、およびクライアントシークレットを認証サーバーに送信することにより、アクセストークンを要求します。 POST
リクエストの例は、次のようになります。
https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
アプリケーションの資格情報がチェックアウトされると、承認サーバーはアプリケーションにアクセストークンを返します。 これで、アプリケーションは独自のアカウントを使用することが許可されます。
注:DigitalOceanは現在、クライアント資格情報付与タイプをサポートしていないため、リンクはoauth.example.com
にある架空の承認サーバーを指します。
付与タイプ:デバイスコード
デバイスコード付与タイプは、ブラウザーがないか、入力が制限されているデバイスがアクセストークンを取得してユーザーのアカウントにアクセスするための手段を提供します。 この付与タイプの目的は、ユーザーがそのようなデバイス上のアプリケーションに自分のアカウントへのアクセスをより簡単に許可できるようにすることです。 これが役立つ場合の例としては、ユーザーがスマートテレビやビデオゲームコンソールなど、一般的なキーボード入力を備えていないデバイスでビデオストリーミングアプリケーションにサインインする場合があります。
デバイスコードフロー
ユーザーは、テレビやセットトップボックスなど、ブラウザのないデバイスまたは入力が制限されたデバイスでアプリケーションを起動します。 アプリケーションは、POST
要求をデバイス認証エンドポイントに送信します。
デバイスコードPOST
リクエストの例は、次のようになります。
POST https://oauth.example.com/device
client_id=CLIENT_id
デバイス認証エンドポイントは実際にはデバイスを認証しないため、デバイス認証エンドポイントは認証サーバーとは異なります。 代わりに、デバイスを識別するために使用される一意のデバイスコードを返します。 ユーザーコード。ラップトップやモバイルデバイスなど、認証が容易なマシンでユーザーが入力できます。 また、ユーザーコードを入力してデバイスを認証するためにユーザーがアクセスする必要のあるURL。
デバイス認証エンドポイントからの応答例は次のようになります。
{
"device_code": "IO2RUI3SAH0IQuESHAEBAeYOO8UPAI",
"user_code": "RSIK-KRAM",
"verification_uri": "https://example.okta.com/device",
"interval": 10,
"expires_in": 1600
}
デバイスコードは、リーダーがモバイルデバイスでスキャンできるQRコードである可能性もあることに注意してください。
次に、ユーザーは指定されたURLにユーザーコードを入力し、自分のアカウントにサインインします。 次に、デバイスにアカウントへのアクセスを許可できる同意画面が表示されます。
ユーザーが確認URLにアクセスしてコードを入力している間、デバイスはエラーまたは認証トークンを返すまでアクセスエンドポイントをポーリングします。 アクセスエンドポイントは、デバイスが頻繁にポーリングしている場合(slow_down
エラー)、ユーザーがまだ要求を承認または拒否していない場合(authorization_pending
エラー)、ユーザーが要求を拒否した場合(access_denied
エラー)、またはトークンの有効期限が切れた場合(expired_token
エラー)。
ただし、ユーザーがリクエストを承認すると、アクセスエンドポイントは認証トークンを返します。
注:繰り返しになりますが、DigitalOceanは現在デバイスコード付与タイプをサポートしていないため、この例のリンクはoauth.example.com
にある架空の認証サーバーを指しています。
アクセストークンの使用例
アプリケーションがアクセストークンを取得すると、トークンが期限切れになるか取り消されるまで、アクセス範囲に限定されたAPIを介してユーザーのアカウントにアクセスするためにトークンを使用できます。
curl
を使用したAPIリクエストの例を次に示します。 アクセストークンが含まれていることに注意してください。
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN""https://api.digitalocean.com/v2/$OBJECT"
アクセストークンが有効であると仮定すると、APIはAPI仕様に従ってリクエストを処理します。 アクセストークンの有効期限が切れているか無効である場合、APIはinvalid_request
エラーを返します。
トークンフローの更新
アクセストークンの有効期限が切れた後、それを使用してAPIからリクエストを行うと、Invalid Token Error
になります。 この時点で、元のアクセストークンが発行されたときに更新トークンが含まれている場合は、それを使用して、認証サーバーに新しいアクセストークンを要求できます。
次に、更新トークンを使用して新しいアクセストークンを取得するPOST
リクエストの例を示します。
https://cloud.digitalocean.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN
結論
このガイドに従うことで、OAuth 2がどのように機能するか、および特定の認証フローをいつ使用する必要があるかを理解できます。
OAuth 2について詳しく知りたい場合は、次の貴重なリソースを確認してください。