認可コード権限付与タイプの実装

認可コードは、特によく使用される OAuth 2.0 の権限付与タイプの 1 つです。認可コードのフローは、「3-legged OAuth」の構成です。この構成では、ユーザーはリソース サーバーで自分自身を認証し、クライアント アプリにユーザー名とパスワードを提供することなく、保護されたリソースへのアプリのアクセスに同意します。

このトピックについて

このトピックでは、OAuth 2.0 の認可権限付与タイプのフローの全般的な説明と概要を示し、Apigee Edge にこのフローを実装する方法について説明します。

動画

OAuth 2.0 認可権限付与タイプを使用して API を保護する方法については、こちらの短い動画をご覧ください。

使用例

この権限付与タイプは、API プロバイダと信頼できるビジネス関係のない、サードパーティのデベロッパーが作成したアプリに使用します。たとえば、公開 API プログラムに登録するデベロッパーは、一般的には信頼しないようにする必要があります。この権限付与タイプでは、リソース サーバー上のユーザーの認証情報がアプリと共有されることはありません。

コードサンプル

Apigee Edge での認可コード権限付与タイプの完全な実装のサンプルは、GitHub の api-platform-samples リポジトリにあります。api-platform-samples/sample-proxies ディレクトリの oauth-advanced サンプル をご覧ください。サンプルの詳細については、README ファイルをご覧ください。

フロー図

次のフロー図は、Apigee Edge を認可サーバーとする、認可コードの OAuth フローを示しています。

ヒント: この図を拡大するには、図を右クリックして新しいタブで開くか、保存して画像ビューアで開きます。

認可コードのフローの手順

Apigee Edge を認可サーバーとする、認可コードの権限付与タイプを実装するために必要なステップの概要を以下に示します。このフローで重要なことは、リソース サーバー上のユーザーの認証情報はクライアントからは見えないということです。

前提条件: クライアント ID とクライアント シークレット キーを取得するには、クライアント アプリを Apigee Edge に登録する必要があります。詳しくは、クライアント アプリの登録をご覧ください。

1. ユーザーがフローを開始する

アプリがリソース サーバーのユーザーの保護されたリソースにアクセスする必要がある場合(ソーシャル メディアサイトの連絡先リストなど)、Apigee Edge に API 呼び出しが送信されます。これにより、クライアントの ID が検証され、有効な場合は、ユーザーが認証情報を入力するログインページにユーザーのブラウザがリダイレクトされます。API 呼び出しには、クライアント アプリが登録されたときに取得した情報(クライアント ID とリダイレクト URI)が含まれます。

2. ユーザーが認証情報を入力する

ユーザーにログインページが表示され、ログイン認証情報の入力を求められます。ログインに成功すると、次のステップに進みます。

3. ユーザーが同意する

このステップでは、ユーザーは、ユーザーのリソースにアプリがアクセスすることに同意します。通常、この同意フォームにはスコープの選択が含まれ、ユーザーは、リソース サーバーでアプリに許可する内容を選択できます。たとえば、ユーザーは読み取り専用権限を与えたり、アプリがリソースを更新する権限を与えたりできます。

4. ログインアプリが Apigee Edge にリクエストを送信する

ログインと同意に成功すると、ログインアプリは Apigee Edge の /authorizationcode エンドポイントにデータを POST します。このデータには、リダイレクト URI、クライアント ID、スコープ、含める必要のあるユーザー固有の情報、ログインに成功した旨が含まれます。

5. Apigee Edge が認可コードを生成する

Edge が /authorizationcode エンドポイントでログインアプリから GET リクエストを受け取ると、2 つのことが行われます。まず、Edge はログインが成功したと判断します(HTTP ステータスのチェックやその他の手段によって)。次に、Edge は、ログインアプリから送信されたリダイレクト URI が、アプリが Apigee Edge に登録されたときに指定されたリダイレクト URI と一致することを確認します。問題がなければ、Edge によって認可コードが生成されます。例:

http://myorg-test.apigee.net/oauth/authorizationcode?client_id={consumer_key}&response_type=code&redirect_uri={redirect_uri}&scope=scope1%20scope2&state={some_string}

6 Edge が認可コードをクライアントに返す

Edge は、クエリ パラメータとしてアタッチされた認可コードを使用して、クライアントに 302 リダイレクトを送信します。

7. クライアントが認可コードを取得し、Edge からのアクセスコードをリクエストする

これで、有効な認可コードを使用して、クライアントは Edge からのアクセス トークンをリクエストできます。これは、クライアント ID とクライアント シークレット キー(アプリが Edge に登録されたときに取得される)、権限付与タイプ、スコープを POST することによって行われます。クライアント ID とクライアント シークレット キーを含めることによって、Apigee Edge はクライアント アプリが登録されていることを確認できます。例:

$ curl https://{org_name}-test.apigee.net/my_oauth_proxy/accesstoken?code=Xyz123&grant_type=authorization_code -X POST -d 'client_id=bBGAQrXgivA9lKu7NMPyoYpKNhGar6K&client_secret=hAr4GngA9vAyvI4'

8. クライアントがアクセス トークンを受け取る

すべてが正常である場合は、Edge によってクライアントにアクセス トークンが返されます。アクセス トークンには有効期限があります。また、これは、ユーザーがリソースへのアプリのアクセスに同意したときに指定したスコープに対してのみ有効です。

9. 保護された API をクライアントが呼び出す

これでクライアントは、有効なアクセスコードを使用することで保護された API を呼び出せるようになりました。このシナリオでは、Apigee Edge(プロキシ)に対してリクエストが行われ、Edge はターゲット リソース サーバーに API 呼び出しを渡す前にアクセス トークンを検証する責任を担います。アクセス トークンは Authorization ヘッダーで渡されます。例:

$ curl -H "Authorization: Bearer ylSkZIjbdWybfs4fUQe9BqP0LH5Z" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

フローとポリシーの構成

Edge は認可サーバーとして、アクセス トークン、認可コード、更新トークン、ログインページのリダイレクトなどのために多数の OAuth リクエストを処理する必要があります。これらのエンドポイントを構成するための基本的なステップは次の 2 つです。

  • カスタムフローの作成
  • OAuthV2 ポリシーの追加と構成

カスタムフロー構成

通常、この権限付与タイプのフローは、フローの各ステップまたは「leg」が Apigee Edge プロキシのフローによって定義されるように構成します。各フローには、エンドポイントと、認可コードやアクセス トークンの生成など、必要な OAuth 固有のタスクを実行するポリシーがあります。たとえば、以下の XML で示すとおり、/oauth/authorizationcode エンドポイントには GenerateAuthCode というポリシー(GenerateAuthorizationCode ポリシーが指定された OAuth2 ポリシー)が関連付けられています。

フローの構成を表示する最も簡単な方法は、XML の例を使用することです。各フローの詳細については、インライン コメントをご覧ください。これは一例であり、必要に応じてフローとパスの名前を構成できます。このようなカスタムフローを作成するために必要な手順の概要については、OAuth エンドポイントとポリシーの構成をご覧ください。

GitHub の実装例もご覧ください。

<Flows>
<Flow name="RedirectToLoginApp">
<!--
Publish this URI to developers to use for their 'login' link
-->
<Condition>proxy.pathsuffix == "/oauth/authorize"</Condition>
<Request>
<Step><Name>RedirectToLoginPage</Name></Step>
</Request>
</Flow>
<Flow name="GetAuthCode">
<!--
Call this URL from your Login app after you authenticate the user.
The policy will automatically return the auth code in the response to the
redirect_uri registered by the calling app
-->
<Condition>proxy.pathsuffix == "/oauth/authorizationcode"</Condition>
<Request>
<Step><Name>GenerateAuthCode</Name></Step>
</Request>
</Flow>
<Flow name="GetAccessToken">
<!-- This policy flow is triggered when the URI path suffix
matches /oauth/accesstoken. Publish this URL to app developers
to use when obtaining an access token using an auth code
-->
<Condition>proxy.pathsuffix == "/oauth/accesstoken"</Condition>
<Request>
<Step><Name>GenerateAccessToken</Name></Step>
</Request>
</Flow>
</Flows>

ポリシーを使用してフローを構成する

各エンドポイントにはポリシーが関連付けられています。ポリシーの例を見てみましょう。OAuthV2 ポリシーをプロキシ エンドポイントに追加するために必要な手順の概要については、OAuth エンドポイントとポリシーの構成もご覧ください。

ログイン リダイレクト

これは /oauth/authorize パスです。接続されたポリシーにより、ユーザーはログインアプリにリダイレクトされます。ログインアプリでは、エンドユーザーはクライアント アプリを安全に認証および認可して、クライアント アプリにユーザー名とパスワードを提供することなく、クライアント アプリが保護されたリソースにアクセスすることを許可します。これは、サービス コールアウト ポリシー、JavaScript、Node.js などの方法を使用して行うことができます。

リクエストを行うための API 呼び出しは GET であり、クエリ パラメータ client_id、response_type、redirect_uri、scope、state が必要です。

$ curl http://myorg-test.apigee.net/oauth/authorize?client_id={consumer_key}&response_type=code&redirect_uri={redirect_uri}&scope=scope1%20scope2&state={some_string}

認可コードを取得する

これは /oauth/authorizationcode パスです。GenerateAuthorizationCode オペレーションが指定されている OAuthV2 ポリシーが使用されています。

<OAuthV2 async="false" continueOnError="false" enabled="true" name="GetAuthCode">
    <DisplayName>GetAuthCode</DisplayName>
    <Operation>GenerateAuthorizationCode</Operation>
    <ExpiresIn>600000</ExpiresIn>
    <GenerateResponse/>
</OAuthV2>

認可コードを取得するための API 呼び出しは GET であり、次の例に示すように、クエリ パラメータ client_id、response_type、および必要に応じて scope、state が必要です。

$curl http://myorg-test.apigee.net/oauth/authorizationcode?client_id={consumer_key}&response_type=code&scope=scope1%20scope2&state={some_string}

アクセス トークンを取得する

このポリシーは、/oauth/accesstoken パスに接続されています。これには、GenerateAccessCode オペレーションが指定されている OAuthV2 ポリシーが使用されています。この場合、grant_type パラメータはクエリ パラメータとして想定されています。

<OAuthV2 name="GetAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>360000000</ExpiresIn>
    <SupportedGrantTypes>
        <GrantType>authorization_code</GrantType>
    </SupportedGrantTypes>
    <GrantType>request.queryparam.grant_type</GrantType>
    <GenerateResponse/>
</OAuthV2>

アクセスコードを取得するための API 呼び出しは POST であり、client_id、client_secret、grant_type=authorization_code、および必要に応じて scope が含まれている必要があります。例:

$ curl https://{org_name}-test.apigee.net/oauth/accesstoken?grant_type=authorization_code -X POST -d 'client_id=bBGAQrXgivA9lKu7NMPyoYpVKNhGar6K&client_secret=hAr4Gn0gA9vAyvI4'

これは基本的な概要にすぎません。作成例には、URL の構築、変換の実施、他のタスクの実行のための、他の数多くのポリシーが含まれています。完全で実用的なプロジェクトについては、GitHub のサンプルをご覧ください。

アクセス トークン検証ポリシーのアタッチ

VerifyAccessToken ポリシー(VerifyAccessToken オペレーションが指定されている OAuthV2 ポリシー)を保護された API にアクセスするすべてのフローの先頭に接続して、保護されたリソースに対するリクエストが発生するたびにこのポリシーが実行されるようにします。Edge は、各リクエストに有効なアクセス トークンがあることを確認します。ない場合は、エラーが返されます。基本的な手順については、アクセス トークンの検証をご覧ください。

<OAuthV2 async="false" continueOnError="false" enabled="true" name="VerifyAccessToken">
    <DisplayName>VerifyAccessToken</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <SupportedGrantTypes/>
    <GenerateResponse enabled="true"/>
    <Tokens/>
</OAuthV2>

保護された API の呼び出し

OAuth 2.0 のセキュリティで保護された API を呼び出すには、有効なアクセス トークンを提示する必要があります。適切なパターンは、次のように Authorization ヘッダーにトークンを含めることです。アクセス トークンは「署名なしトークン」とも呼ばれます。

$ curl -H "Authorization: Bearer UAj2yiGAcMZGxfN2DhcUbl9v8WsR" \
  http://myorg-test.apigee.net/v0/weather/forecastrss?w=12797282

アクセス トークンの送信もご覧ください。