認可プロバイダ・ファンクションを使用したAPIデプロイメントへの認証および認可の追加
APIゲートウェイにデプロイするAPIへのアクセスは、認可プロバイダ・ファンクション(このトピックで説明)またはJWT (JSON Webトークン(JWT)を使用したAPIデプロイメントへの認証および認可の追加を参照)を使用して制御できます。
APIゲートウェイに認証および認可機能を追加するには、次のような「認可プロバイダ・ファンクション」を記述します:
- リクエスト属性を処理して、アイデンティティ・プロバイダでエンド・ユーザーのアイデンティティを確認します。
- エンド・ユーザーが実行を許可される操作を決定します。
- 「アクセス・スコープ」のリストとして、エンド・ユーザーが実行を許可されている操作を返します(「アクセス・スコープ」は、アクセスの決定に使用される任意の文字列です)。
- オプションで、APIデプロイメントで使用するキーと値のペアを返します。たとえば、HTTPバック・エンド定義で使用するコンテキスト変数です(ポリシーおよびHTTPバック・エンド定義へのコンテキスト変数の追加を参照)。
その後、認可プロバイダ・ファンクションをOracle Functionsにデプロイします。認可プロバイダ・ファンクションの作成を参照してください。認可プロバイダ・ファンクションの例が示された関連する開発者チュートリアルについては、ファンクション: APIゲートウェイを使用したAPIキーの検証を参照してください。
認可プロバイダ・ファンクションをデプロイした後、APIデプロイメント仕様に2種類の異なるリクエスト・ポリシーを含めることにより、APIデプロイメントに対する認証および認可を有効にします:
- 次を指定するAPIデプロイメント全体の認証リクエスト・ポリシー:
- 認証および認可を実行するOracle Functionsにデプロイした認可プロバイダ・ファンクションのOCID。
- 認可プロバイダ・ファンクションに渡すリクエスト属性。
- 認証されていないエンド・ユーザーがAPIデプロイメントのルートにアクセスできるかどうか。
- 認可プロバイダ・ファンクションにより返されたエンド・ユーザーのアクセス・スコープに基づいてエンド・ユーザーが実行できる操作を指定する、各ルートの認可リクエスト・ポリシー。
次を実行して、認証および認可リクエスト・ポリシーをAPIデプロイメント仕様に追加できます:
- コンソールの使用。
- JSONファイルの編集。
認可プロバイダ・ファンクションの問題のトラブルシューティングについては、ログ・レベルを「情報」に設定して、APIデプロイメントに実行ログを追加することを検討してください(APIデプロイメントへのロギングの追加を参照)。
認証および認可に関連するログ・ファイルの詳細を表示するには、customAuth
を検索します。
認可プロバイダ・ファンクションを使用するための前提条件
認可プロバイダ・ファンクションを使用してAPIデプロイメントの認証および認可を有効化する前に:
- アイデンティティ・プロバイダ(たとえば、Oracle Identity Cloud Service (IDCS)、Auth0)は、すでに設定されている必要があります(APIデプロイメントへのアクセスを許可されたユーザーのアクセス・スコープを含む)。詳細は、アイデンティティ・プロバイダ・ドキュメント(たとえば、Oracle Identity Cloud Service (IDCS)ドキュメント、Auth0ドキュメント)を参照してください。
- 認可プロバイダ・ファンクションは、すでにOracle Functionsにデプロイされている必要があります。適切なポリシーにより、APIゲートウェイにOracle Functionsへのアクセス権が付与されている必要があります。詳細は、認可プロバイダ・ファンクションの作成を参照してください。
コンソールを使用して(JSONファイルの編集ではなく)認証リクエスト・ポリシーを含める場合は、認可プロバイダ・ファンクションおよびそれを含むアプリケーションをリストから選択します。
(JSONファイルではなく)コンソールを使用して認証リクエスト・ポリシーを定義し、認可プロバイダ・ファンクションを指定するには、IAMポリシーによって認可プロバイダ・ファンクションへのアクセス権が付与されたグループにユーザー・アカウントが属している必要があります(ファンクションへのAPIゲートウェイ・ユーザー・アクセスを提供するポリシーの作成を参照)。
認可プロバイダ・ファンクションの作成
認可プロバイダ・ファンクションを作成するには:
-
認証および認可を実装するコードを記述します:
-
APIゲートウェイからの次のJSON入力を受け入れる認可プロバイダ・ファンクションのコードを記述します:
{ "type": "TOKEN", "token": "<token-value>" }
ここでは:
"type": "TOKEN"
は、認可プロバイダ・ファンクションに渡される値が認証トークンであることを示します。"token": "<token-value>"
は、認可プロバイダ・ファンクションに渡される認証トークンです。
例:
{ "type": "TOKEN", "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1nHyDtTwR3SEJ3z489..." }
-
アクセス・トークンが正常に検証されたときに、次のJSONをHTTP 200レスポンスとしてAPIゲートウェイに戻す認可プロバイダ・ファンクションのコードを記述します:
{ "active": true, "principal": "<user-principal>", "scope": ["<scopes>"], "clientId": "<client-id>", "expiresAt": "<date-time>", "context": { "<key>": "<value>", ... } }
ここでは:
"active": true
は、当初認可プロバイダ・ファンクションに渡されたアクセス・トークンが正常に検証されたことを示します。"principal": "<user-principal>"
は、アイデンティティ・プロバイダの認可プロバイダ・ファンクションによって取得されるユーザーまたはアプリケーションです。-
"scope": ["<scopes>"]
は、アイデンティティ・プロバイダの認可プロバイダ・ファンクションによって取得されるアクセス・スコープである文字列のカンマ区切りリストです。 "clientId": "<client-id>"
は、オプションでリクエスタのホスト(たとえば、ホスト名またはクライアントIP)です。clientId
を戻す必要はありません。-
"expiresAt": "<date-time>"
は、ISO-8601フォーマットの日時文字列で、最初に認可プロバイダ・ファンクションに渡されるアクセス・トークンの期限を示します。この値は、認可プロバイダ・ファンクションのコール後に結果のキャッシュ期間を決定する際に使用されます。 -
"context": {"<key>": "<value>", ... }
は、APIゲートウェイに戻るための、JSONフォーマットのキーと値のペアのオプションのカンマ区切りリストです。認可プロバイダ・ファンクションは、APIデプロイメントで使用する任意のキーと値のペア(たとえば、エンド・ユーザーのユーザー名や電子メール・アドレス)を返すことができます。認可プロバイダ・ファンクションによって返されるキーと値のペアでの値をHTTPバック・エンド定義のコンテキスト変数として使用する際の詳細は、ポリシーおよびHTTPバック・エンド定義へのコンテキスト変数の追加を参照してください。
例:
{ "active": true, "principal": "https://example.com/users/jdoe", "scope": ["list:hello", "read:hello", "create:hello", "update:hello", "delete:hello", "someScope"], "clientId": "host123", "expiresAt": "2019-05-30T10:15:30+01:00", "context": { "email": "john.doe@example.com" } }
-
トークン検証に失敗した場合あるいは認可プロバイダ・ファンクションまたはOracle Functionsでエラーが発生した場合に、HTTP 5xxレスポンスとしてAPIゲートウェイに次のJSONを返すコードを記述します:
{ "active": false, "wwwAuthenticate": "<directive>" }
ここでは:
"active": false
は、最初に認可プロバイダ・ファンクションに渡されたアクセス・トークンが正常に検証されていないことを示します。"wwwAuthenticate": "<directive>"
は、検証が失敗した場合に認可プロバイダ・ファンクションによって戻されるWWW-Authenticateヘッダーの値で、必要な認証のタイプ(BasicやBearerなど)を示します。APIゲートウェイは、WWW-AuthenticateヘッダーをAPIクライアントへのレスポンスで返し、401ステータス・コードも返します。たとえば、"wwwAuthenticate": "Bearer realm=\"example.com\""
です。詳細は、RFC 2617 HTTP Authentication: Basic and Digest Access Authenticationを参照してください。
例:
{ "active": false, "wwwAuthenticate": "Bearer realm=\"example.com\"" }
認可プロバイダ・ファンクションの例が示された関連する開発者チュートリアルについては、ファンクション: APIゲートウェイを使用したAPIキーの検証を参照してください。
-
-
コードからDockerイメージを作成し、DockerイメージをDockerレジストリにプッシュして、イメージに基づいてOracle Functionsで新しいファンクションを作成します。これは、様々な方法で実行できます:
- Fn Project CLIコマンド
fn deploy
を使用して、新しいDockerイメージを作成し、Dockerレジストリにイメージをプッシュし、イメージに基づいてOracle Functionsに新しいファンクションを作成できます。ファンクションの作成およびデプロイを参照してください。 - Dockerコマンドを使用してイメージを作成し、Dockerレジストリにプッシュしてから、Fn Project CLIコマンド
fn create function
(またはCreateFunction
API操作)を使用して、イメージに基づいてOracle Functionsに新しいファンクションを作成できます。既存のDockerイメージからのファンクションの作成を参照してください。
- Fn Project CLIコマンド
- Oracle Functionsに作成するファンクションのOCIDをノートにとります。たとえば、
ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq
です -
まだ存在しない場合は、Oracle Cloud Infrastructureポリシーを作成し、APIゲートウェイにファンクション関連リソースへのアクセス権を付与するポリシー・ステートメントを指定します。ポリシーによって、これらのAPIゲートウェイのAPIデプロイメントで認可プロバイダ・ファンクションを起動できます。詳細は、APIゲートウェイにファンクションへのアクセス権を付与するポリシーの作成を参照してください
コンソールを使用した認証および認可リクエスト・ポリシーの追加
コンソールを使用してAPIデプロイメント仕様に認証および認可リクエスト・ポリシーを追加するには:
-
コンソールを使用してAPIデプロイメントを作成または更新し、「最初から」オプションを選択して、「基本情報」ページで詳細を入力します。
詳細は、APIデプロイメントの作成によるAPIゲートウェイへのAPIのデプロイおよびAPIゲートウェイおよびAPIデプロイメントの更新を参照してください。
-
「基本情報」ページの「APIリクエスト・ポリシー」セクションで、「認証」の横の「追加」ボタンをクリックし、次を指定します:
- 認証タイプ: 「カスタム」を選択します。
- <compartment-name>のアプリケーション: 認可プロバイダ・ファンクションを含むOracle Functionsのアプリケーションの名前。別のコンパートメントからアプリケーションを選択できます。
- ファンクション名: Oracle Functionsの認可プロバイダ・ファンクションの名前。
- 認証トークン: アクセス・トークンがリクエスト・ヘッダーに含まれるか問合せパラメータに含まれるか。
-
認証トークンの値: アクセス・トークンがリクエスト・ヘッダーに含まれるか問合せパラメータに含まれるかに応じて、次を指定します:
- ヘッダー名: アクセス・トークンがリクエスト・ヘッダーに含まれている場合は、ヘッダーの名前を入力します。
- パラメータ名: アクセス・トークンが問合せパラメータに含まれる場合は、問合せパラメータの名前を入力します。
- 匿名アクセスの有効化: 未認証(つまり、匿名)のエンド・ユーザーがAPIデプロイメント内のルートにアクセスできるかどうか。デフォルトでは、このオプションは選択されていません。匿名のユーザーがルートにアクセスできないようにする場合は、このオプションを選択しないでください。このオプションを選択した場合は、各ルートの認可ポリシーで「匿名」を「認可タイプ」として選択することで、匿名アクセスを許可する各ルートを明示的に指定する必要もあります。
-
「変更の保存」をクリックし、「次」をクリックして、「ルート」ページのAPIデプロイメント内の個々のルートの詳細を入力します。個々のルートに適用する認可ポリシーを指定するには、「リクエスト・ポリシーのルーティングを表示」をクリックし、「認可」の横にある「追加」ボタンをクリックして、次を指定します:
-
認可タイプ: ルートへのアクセス権を付与する方法。次を指定します:
- 任意: 認可プロバイダ・ファンクションで「許可されるスコープ」フィールドに指定したアクセス・スコープのいずれかも戻された場合にのみ、正常に認証されたエンド・ユーザーにアクセス権を付与します。この場合、認証ポリシーの「匿名アクセスの有効化」オプションは無効です。
- 匿名: 認可プロバイダ・ファンクションによって正常に認証されていない場合でも、すべてのエンド・ユーザーにアクセス権を付与します。この場合、認証ポリシーの「匿名アクセスの有効化」オプションを選択しておく必要があります。
- 認証のみ: 認可プロバイダ・ファンクションによって正常に認証されたエンド・ユーザーにのみアクセス権を付与します。この場合、認証ポリシーの「匿名アクセスの有効化」オプションは無効です。
- 許可されるスコープ: 認可タイプとして「任意」を選択した場合は、認可プロバイダ・ファンクションから返されたアクセス・スコープに対応する1つ以上の文字列のカンマ区切りリストを入力します。アクセス権は、指定したアクセス・スコープのいずれかが認可プロバイダ・ファンクションによって返された場合に、正常に認証されたエンド・ユーザーにのみ付与されます。たとえば、
read:hello
です
ノート
特定のルートの認可ポリシーを含めない場合、そのようなポリシーが存在するかのようにアクセスが付与され、「認可タイプ」が「認証のみ」に設定されます。つまり、認証ポリシーの「匿名アクセスの有効化」オプションの設定に関係なく、次のようになります:
- ルートにアクセスできるのは、認証されたエンド・ユーザーのみです
- 認証されたすべてのエンド・ユーザーは、認可プロバイダ・ファンクションから返されたアクセス・スコープに関係なく、ルートにアクセスできます
- 匿名のエンド・ユーザーはルートにアクセスできません
-
- 「変更の保存」をクリックし、「次」をクリックしてAPIデプロイメントに入力した詳細を確認します。
- APIデプロイメントを作成または更新するには、「作成」または「変更の保存」をクリックします。
- (オプション) コールしてAPIが正常にデプロイされていることを確認します(APIゲートウェイにデプロイされたAPIのコールを参照)。
JSONファイルの編集による認証および認可リクエスト・ポリシーの追加
JSONファイルのAPIデプロイメント仕様に認証および認可リクエスト・ポリシーを追加するには:
-
任意のJSONエディタを使用して、認証および認可機能を追加する既存のAPIデプロイメント仕様を編集するか、新しいAPIデプロイメント仕様を作成します(APIデプロイメント仕様の作成を参照)。
APIデプロイメント仕様には、少なくとも次の内容を含む
routes
セクションが含まれます:- パス。たとえば、
/hello
です - 1つ以上のメソッド。たとえば、
GET
です - バック・エンドの定義。たとえば、URLまたはOracle Functions内のファンクションのOCIDです。
たとえば、次の基本的なAPIデプロイメント仕様では、単純なOracle FunctionsのHello Worldサーバーレス・ファンクションを単一のバック・エンドとして定義しています:
{ "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" } } ] }
- パス。たとえば、
-
APIデプロイメント仕様のすべてのルートに適用する
authentication
リクエスト・ポリシーを追加します:-
routes
セクションの前にrequestPolicies
セクションを挿入します(まだ存在しない場合)。例:{ "requestPolicies": {}, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" } } ] }
-
次の
authentication
ポリシーを新しいrequestPolicies
セクションに追加します。{ "requestPolicies": { "authentication": { "type": "<type-value>", "isAnonymousAccessAllowed": <true|false>, "functionId": "<function-ocid>", <"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>"> } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" } } ] }
ここでは:
-
<type-value>
は認証タイプです。認証に認可プロバイダ・ファンクションを使用するには、CUSTOM_AUTHENTICATION
を指定します。 "isAnonymousAccessAllowed": <true|false>
は、オプションで、未証(つまり、匿名)のエンド・ユーザーがAPIデプロイメント仕様のルートにアクセスできるかどうかを示します。匿名のエンド・ユーザーがルートにアクセスできないようにする場合は、このプロパティをfalse
に設定します。このプロパティをauthentication
ポリシーに含めない場合、デフォルトのfalse
が使用されます。このプロパティを使用してtrue
に設定する場合は、各ルートのauthorization
ポリシーでtype
プロパティを"ANONYMOUS"
に設定することで、匿名アクセスが許可されているすべてのルートを明示的に指定する必要もあります。-
<function-ocid>
は、Oracle Functionsにデプロイされた認可プロバイダ・ファンクションのOCIDです。 <"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>">
は、アクセス・トークンを含むリクエスト・ヘッダーであるか(そうであれば、ヘッダーの名前)またはアクセス・トークンを含む問合せパラメータであるか(そうであれば、問合せパラメータの名前)を示します。"tokenHeader": "<token-header-name>"
または"tokenQueryParam": "<token-query-param-name>">
のいずれかを指定できますが、両方を指定することはできません。
たとえば、次の
authentication
ポリシーでは、認可リクエスト・ヘッダーのアクセス・トークンを検証するOCIファンクションを指定します:{ "requestPolicies": { "authentication": { "type": "CUSTOM_AUTHENTICATION", "isAnonymousAccessAllowed": false, "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq", "tokenHeader": "Authorization" } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" } } ] }
-
-
-
APIデプロイメント仕様の各ルートに、
authorization
リクエスト・ポリシーを追加します:-
最初のルートの
backend
セクションの後にrequestPolicies
セクションを挿入します(まだ存在しない場合)。例:{ "requestPolicies": { "authentication": { "type": "CUSTOM_AUTHENTICATION", "isAnonymousAccessAllowed": false, "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq", "tokenHeader": "Authorization" } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" }, "requestPolicies": {} } ] }
-
次の
authorization
ポリシーをrequestPolicies
セクションに追加します:{ "requestPolicies": { "authentication": { "type": "CUSTOM_AUTHENTICATION", "isAnonymousAccessAllowed": false, "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq", "tokenHeader": "Authorization" } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" }, "requestPolicies": { "authorization": { "type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS">, "allowedScope": [ "<scope>" ] } } } ] }
ここでは:
-
"type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS">
は、ルートへのアクセス権を付与する方法を示します:"AUTHENTICATION_ONLY"
: 正常に認証されたエンド・ユーザーにのみアクセス権を付与します。この場合、APIデプロイメント仕様のauthentication
ポリシーの"isAnonymousAccessAllowed"
プロパティは無効です。"ANY_OF"
: 認可プロバイダ・ファンクションによって、allowedScope
プロパティで指定したアクセス・スコープのいずれかも戻された場合に、正常に認証されたエンド・ユーザーにのみアクセス権を付与します。この場合、APIデプロイメント仕様のauthentication
ポリシーの"isAnonymousAccessAllowed"
プロパティは無効です。"ANONYMOUS"
: 正常に認証されていない場合でも、すべてのエンド・ユーザーにアクセス権を付与します。この場合、APIデプロイメント仕様のauthentication
ポリシーで"isAnonymousAccessAllowed"
プロパティを明示的にtrue
に設定する必要があります。
-
"allowedScope": [ "<scope>" ]
は、認可プロバイダ・ファンクションによって戻されるアクセス・スコープに対応する1つ以上の文字列のカンマ区切りリストです。この場合、type
プロパティを"ANY_OF"
に設定する必要があります(type
プロパティが"AUTHENTICATION_ONLY"
または"ANONYMOUS"
に設定されている場合、"allowedScope"
プロパティは無視されます)。また、複数のスコープを指定した場合、指定したスコープのいずれかが認可プロバイダ・ファンクションによって戻されると、ルートへのアクセス権が付与されることにも注意してください。
たとえば、次のリクエスト・ポリシーは、
read:hello
スコープを持つ認証されたエンド・ユーザーのみにアクセスを許可する/hello
ルートを定義します:{ "requestPolicies": { "authentication": { "type": "CUSTOM_AUTHENTICATION", "isAnonymousAccessAllowed": false, "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq", "tokenHeader": "Authorization" } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" }, "requestPolicies": { "authorization": { "type": "ANY_OF", "allowedScope": [ "read:hello" ] } } } ] }
-
- APIデプロイメント仕様内の残りのすべてのルートに、
authorization
リクエスト・ポリシーを追加します。
ノート
特定のルートの
authorization
ポリシーを含めない場合、そのようなポリシーが存在し、type
プロパティが"AUTHENTICATION_ONLY"
に設定されているかのように、アクセス権が付与されます。つまり、APIデプロイメント仕様のauthentication
ポリシーでのisAnonymousAccessAllowed
プロパティの設定に関係なく、次のようになります:- ルートにアクセスできるのは、認証されたエンド・ユーザーのみです
- 認証されたすべてのエンド・ユーザーは、認可プロバイダ・ファンクションから返されたアクセス・スコープに関係なく、ルートにアクセスできます
- 匿名のエンド・ユーザーはルートにアクセスできません
-
- APIデプロイメント仕様を含むJSONファイルを保存します。
-
APIデプロイメント仕様は、次の方法でAPIデプロイメントを作成または更新するときに使用します:
- 「既存のAPIのアップロード」オプションを選択して、コンソールでJSONファイルを指定します
- APIゲートウェイREST APIへのリクエストでJSONファイルを指定します
詳細は、APIデプロイメントの作成によるAPIゲートウェイへのAPIのデプロイおよびAPIゲートウェイおよびAPIデプロイメントの更新を参照してください。
- (オプション) コールしてAPIが正常にデプロイされていることを確認します(APIゲートウェイにデプロイされたAPIのコールを参照)。