2024年6月26日水曜日

Oracle IAMのOIDC認証にてAPEXアプリとそれから呼び出すORDSのREST APIを認証する

Oracle IAMをIdMとしたOpenID Connect認証と、そのアクセス・トークンを使用したORDS REST APIの認証の実装手順を確認します。

テスト用のアプリケーションの作成およびOracle IDCS、Oktaでの実装手順は、以下の記事で紹介しています。
ORDS 23.3で追加されたOAUTH.CREATE_JWT_PROFILEを使ってRESTサービスを保護する

Microsoft Entra IDでの実装手順は、以下の記事で紹介しています。
Microsoft Entra IDのOIDC認証にてAPEXアプリとそれから呼び出すORDSのREST APIを認証する

Oracle IAMでのOpenID Connect認証の設定手順は、Oracle Help Center Learnから公開されている、以下の資料に沿って作業を行います。
Integrate Oracle APEX with Oracle Cloud Infrastructure Identity and Access Management Identity Domains

すでにAPEXアプリケーションとしてORDS JWT Testが作成済みとし、Oracle IAMでの機密アプリケーションの追加から始めます。

実装には、Always Freeの範囲で使用できるDefaultドメインを使います。

Oracle Cloudのコンソールにサインインし、プロファイルのメニューよりアイデンティティ・ドメイン: Defaultを開きます。


アイディンティティ・ドメインDefaultの概要が開きます。左上のナビゲーションからのメニュー・パスとしては、アイデンティティとセキュリティからドメインを開き、ドメインDefaultを開いた状態です。

ドメイン情報ドメインURLがあります。これをコピーして保存します。


Oracle APEXの認証スキームを作成する際に設定する、OpenID Connectプロバイダ検出URLは、このドメインURL/.well-known/openid-configurationを付加したURLになります。

検出URL: https://ドメインURL/.well-known/openid-configuration

また、OAUTH.CREATE_JWT_PROFILEの引数p_jwk_urlの値は、ドメインURLに/admin/v1/SigningCert/jwkを付加したURLになります。

JSON Web Keyの取得URL: https://ドメインURL/admin/v1/SigningCert/jwk

これらの値は、後続の設定で使用します。

Defaultドメインの設定を開きます。


ドメイン設定署名証明書へのアクセスクライアント・アクセスの構成チェックを入れます。Oracle IAMではJWTの署名を検証するための証明書を取得するURLは、デフォルトで保護されています。その保護を解除します。

変更を保存します。


Defaultドメインに戻り、セキュリティを開きます。


OAuthを開くと、発行者という設定があります。これはオプションで、無指定の場合は発行者は以下になります。

発行者: https://identity.oraclecloud.com/

この値は、JWTのアクセス・トークンのiss属性の値になります。また、OAUTH.CREATE_JWT_PROFILEを呼び出す際に、引数p_issuerとして指定する値になります。


DefaultドメインにAPEXアプリケーションを追加します。

Defaultドメイン統合アプリケーションを開き、アプリケーションの追加をクリックします。


機密アプリケーションを選択し、ワークフローの起動をクリックします。


追加する機密アプリケーションの名前ORDS JWT Testとします。画面の下を表示するよう、スクロールします。


認証と認可権限付与を認可として実施チェックします。このアプリケーションに割り当てられたユーザーおよびグループのみがサインインできるようになります。

へ進みます。


リソース・サーバー構成このアプリケーションをリソース・サーバーとして今すぐ構成しますを選択します。

リソース・サーバーの構成は、アクセス・トークンのscopeクレイムに、ORDSを保護している権限を追加するために必要な設定です。ORDSの保護にJWTを使わない場合は、この設定は不要です。

プライマリ・オーディエンスとしてords/myapplication/を設定します。ここでは任意の名前を設定できますが、この値はアクセス・トークンのaud属性になります(より正確にはaud属性が配列になるため、その要素の1つになります)。また、OAUTH.CREATE_JWT_PROFILEの引数p_audienceへ与える値になります。後の設定で使うので、覚えておきます。

スコープの追加にチェックを入れ、スコープの追加をクリックします。


スコープには、ORDSのAPIを保護している権限と同じ名前を設定します。今回は、myordsappします。ORDSの権限としてmyordsappが作成されていることを前提としています。

ユーザー許諾が必要チェックを入れます。ここでチェックが入っていると、アプリケーションへの初回サインイン時に、このスコープの使用を許可するかどうかをユーザーに確認します。

追加をクリックします。


リソース・サーバー構成は以上で完了です。

クライアント構成このアプリケーションをクライアントとして今すぐ構成しますを選択します。


認可許可される権限付与タイプから、認可コードチェックを入れます。OAuth2のAuthorization Code Grantsのことです。リダイレクトURLとして、APEXをホストしているサーバーのURLにapex_authentication.callbackを付加したURLを設定します。

Autonomous Databaseの場合は、リダイレクトURLは以下のようになります。
https://[インスタンスID]-[DB名].adb.[リージョン]
.oraclecloudapps.com/ords/apex_authentication.callback

ログアウト後のリダイレクトURLはオプションですが、以下のようにORDS JWT Testのアプリケーションに戻るようにします。
https://[インスタンスID]-[DB名].adb.[リージョン]
.oraclecloudapps.com/ords/f?p=[ORDS JWT TestのアプリケーションID]

トークン発行ポリシーの設定も必要ですが、アプリケーションを作成するまではリソースを参照できません。

へ進みます。


Web層ポリシーは設定しません。スキップして後で実行を選択します。

終了をクリックします。


アプリケーションORDS JWT Testが作成されます。

トークン発行ポリシーを設定するため、OAuth構成の編集をクリックします。


トークン発行ポリシー特定になっています)のリソースの追加チェックします。リソースが開くので、そこでスコープの追加をクリックします。


ORDS JWT Testをチェックします。

追加をクリックします。


リソースとしてORDS JWT Testが追加され、そのスコープords/myapplication/myordsappとして表示されています。この値をアプリケーションORDS JWT Test認証スキーム有効範囲(つまりscopeのこと)に含めることにより、APEXアプリケーションへのサインイン時にORDS REST APIを呼び出す許可を同時に取得します。

変更の保存をクリックします。


アプリケーションをアクティブ化します。確認画面が開くので、アプリケーションのアクティブ化をクリックします。


アプリケーションがアクティブ化されたら、リソースユーザーを開き、このアプリケーションにサインインできるユーザーの割当てを実施します。


アプリケーションに割り当てるユーザーを選択し、割当てをクリックします。


以上でOracle IAMへの機密アプリケーションの追加は完了しました。


リソースからOAuth構成を開き、一般情報クライアントIDクライアント・シークレットを取得します。これらの値は、APEXのWeb資格証明クライアントIDまたはユーザ名およびクライアント・シークレットまたはパスワードとして設定します。


Oracle APEXおよびORDSへの設定に必要な情報もすべて集まりました。

JWTのアクセス・トークンによるORDS REST APIへのアクセスを許可するため、OAUTH.CREATE_JWT_PROFILEを呼び出します。

ORDSを実行しているワークスペースのSQLコマンドより、以下のコマンドを実行します。引数p_jwk_urlに与えるURLはあらかじめブラウザよりアクセスして、署名証明書が取得できることを確認しておくと良いでしょう。
begin
    oauth.create_jwt_profile(
        p_issuer => 'https://identity.oraclecloud.com/'
        ,p_audience => 'ords/myapplication/'
        ,p_jwk_url => 'https://[ドメインURL]/admin/v1/SigningCert/jwk'
    );
end;
引数p_issuerp_audienceの値は、今までの手順通り作業を行なっている場合の値です。


APEXアプリケーションの認証スキームで使用するWeb資格証明を作成します。

名前Oracle IAM静的IDORACLE_IAMとしています。認証タイプとしてOAuth2クライアント資格証明を選択します。

クライアントIDまたはユーザー名として、Oracle IAMに追加した機密アプリケーションのクライアントIDクライアント・シークレットまたはパスワードとして、クライアント・シークレットを設定します。


アプリケーションORDS JWT Testに、Oracle IAMをIdPとした認証スキームを作成します。

名前Oracle IAMとし、スキーム・タイプとしてソーシャル・サインインを選択します。

資格証明ストアとして作成済みのWeb資格証明Oracle IAMを選択します。認証プロバイダOpenID Connectプロバイダを選択します。検出URLを設定し、有効範囲として以下を設定します。

profile,email,ords/myapplication/myordsapp


アプリケーションORDS JWT Testでは、ソースPL/SQLコードとしてプロシージャpost_authを記述し、それをログイン・プロセス認証後のプロシージャ名に設定しています。


Oracle Help Center Learnのチュートリアルでは、この部分は以下のようなコードを記述し、APEXの動的グループを作成しています。本記事では動的グループについては扱いません。
procedure load_dynamic_groups as
  l_group_names apex_t_varchar2;
begin
  --
  -- add all group names to l_group_names
  --
  for i in 1 .. apex_json.get_count('groups') loop
      apex_string.push (
        p_table => l_group_names,
        p_value => apex_json.get_varchar2 (
                       p_path => 'groups[%d].name',
                       p0     => i ));
  end loop;
  --
  -- save group names in session
  --
  apex_authorization.enable_dynamic_groups (
      p_group_names => l_group_names );
end;
以上で、Oracle APEX側の準備も完了です。

アプリケーションを実行し、動作を確認します。

Defaultドメインへのサインイン画面が表示されます。(アプリケーションに自分のアカウントをユーザーとして割り当てているため)Oracle Cloudのコンソールへのサインインに使用しているユーザー名パスワードを入力します。

サインインをクリックします。


(MFAの設定によりますが)Oracle Mobile Authenticatorによる許可を求められます。


Oracle Mobile Authenticatorでアクセスを許可すると、要求したスコープへのアクセスの許可を求められます。この中にords/myapplication/myordsappが含まれています。

許可をクリックします。

アプリケーションのホーム画面が開きます。

User InfoにはOracle IAMから取得したアクセス・トークンの情報がデコードされて表示されています。

すでにORDSにはJWTのプロファイルを作成しているため、REST API Responseも401 Unauthorizedではなく、ORDS REST APIのレスポンスが表示されています。


今回の記事は以上です。

Oracle IAMが発行したアクセス・トークンを使って、ORDSのREST APIを認証できることが確認できました。