2024年9月2日月曜日

APEX 24.1でのデータベース資格証明のサポートを確認する

Oracle APEX 24.1から、Web資格証明の属性としてデータベース資格証明の使用が追加されました。基本認証OAuth2クライアント資格証明認証タイプが対応しています。


データベース資格証明は、一般的にDBMS_CLOUD.CREATE_CREDENTIALを呼び出して作成します。マニュアルに構文が記載されていますが、基本認証(いわゆるHTTPのBasic認証)については、以下の構文で作成したデータベース資格証明を参照すればよいことは分かります。
DBMS_CLOUD.CREATE_CREDENTIAL (
	credential_name   IN VARCHAR2,
	username          IN VARCHAR2,
	password          IN VARCHAR2 DEFAULT NULL);
DBMS_COUD.CREATE_CREDENTIALには、OAuth2のクライアントIDとクライアント・シークレットを保存するシグネチャはありません。

Oracle APEXのWeb資格証明OAuth2クライアント資格証明として使用するデータベース資格証明は、usernameクライアントIDpasswordクライアント・シークレットを指定して作成します。

AWSのARNを使ったデータベース資格証明(参考記事)、Azureのリソース・プリンシパルを使ったデータベース資格証明(参考記事)、Googleのサービス・アカウントを使ったデータベース資格証明(参考記事)を元にAPEXのWeb資格証明を作ることができるのかと当初は考えたのですが、そのような機能ではありませんでした。

OAuth2のClient Credentialsフローでは、認証サーバーはクライアント認証を行う際にBasic認証の実装は必須です(RFC 6749 2.3.1 Client Password)。そのため、Oracle APEXのWeb資格証明の認証タイプの基本認証とOAuth2の両方で、内部的にBasic認証(認証の対象は基本認証ではリソース・サーバー、OAuth2では認証サーバー)を使用していると思われます。Autonomous DatabaseのドキュメントではパッケージUTL_HTTPにSET_CREDENTIALというプロシージャが定義され、このプロシージャを呼び出すことによりBasic認証に必要なAuthorizationヘッダーが追加されると説明されています。

手短に説明すると、APEXのWeb資格証明として基本認証やOAuth2クライアント資格証明を作成するのと、これらをデータベース資格証明を元に作成するのとで、できることできないことに違いはありません。ユーザー名とシークレットの保存先が変わるだけです。異なる点は、データベース資格証明を元にしたWeb資格証明では、URLに対して有効を設定できないことと、HTTPのリクエストを発行するプリンシパルが、APEXのインストール・ユーザーではなくワークスペース・スキーマになることです。

以前の記事「ORDS REST APIのOAuth2による保護とAPEXからの呼び出し」で作成したアプリケーションを使って、Web資格証明データベース資格証明を元にしたものに変えてみます。

以下のアプリケーションをダウンロードして、ワークスペースにインポートします。
https://github.com/ujnak/apexapps/blob/master/exports/ords-rest-test.zip

アプリケーションをインポートする際に、このアプリケーションで参照しているWeb資格証明としてHR Example Credが作成されます。また、ORDSのREST APIを指すリモート・サーバーとしてRemote Server for Cred HR ExampleおよびRemote Server for RDS HR Exampleが作成されます。


記事に従ってRESTサービスのセットアップが完了していれば、OAuth2のクライアントIDとクライアント・シークレットが作成されています。

ビューUSER_ORDS_CLIENTSを検索し、CLIENT_IDCLIENT_SECRETを確認します。

select name, client_id, client_secret from user_ords_clients;


アプリケーションのインポート時に作成されたWeb資格証明HR Example Credを開き、クライアントIDクライアント・シークレットを更新します。


共有コンポーネントリモート・サーバーを開きます。

Remote Server for Cred HR Example(タイプが認証のリモート・サーバー)、Remote Server for RDS HR Example(タイプがRESTデータ・ソースのリモート・サーバー)を編集します。


それぞれのリモート・サーバーエンドポイントURLを環境に合わせて変更します。


Web資格証明とリモート・サーバーの設定を変更すると、テスト用のアプリケーションを実行できます。

ホーム・ページの表示です。


RESTデータ・ソースのレポートです。


これから、Web資格証明HR Example Credデータベース資格証明を使うように変更します。

DBMS_CREDENTIAL.CREATE_CREDENTIALを呼び出し、データベース資格証明としてHR_EXAMPLE_CREDを作成します。
begin
    dbms_cloud.create_credential(
        credential_name => 'HR_EXAMPLE_CRED'
        ,username       => 'クライアントID'
        ,password       => 'クライアント・シークレット'
    );
end;

作成したデータベース資格証明を確認します。

select * from user_credentials


今回は実行しませんが、データベース資格証明の削除には、DBMS_CREDENTIAL.DROP_CREDENTIALを呼び出します。

 Web資格証明HR Example Credを開き、データベース資格証明を参照するように設定を変更します。

データベース資格証明の使用オンにし、データベース資格証明名前としてHR_EXAMPLE_CREDを設定します。ストアド・トークンが存在する場合は、認証済みのセッションが継続しないようにトークンのクリアを実施しておきます。

変更の適用をクリックします。


データベース資格証明を元にしたWeb資格証明を使用する場合、HTTPのリクエストはAPEXがインストールされているスキーマではなく、ワークスペース・スキーマがプリンシパルとなります。

そのためネットワークACLを、ワークスペース・スキーマにたいして追加する必要があります。
begin
    DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
        host => '*',
        ace  =>  xs$ace_type(
            privilege_list => xs$name_list('connect', 'resolve'),
            principal_name => 'ワークスペース・スキーマ',
            principal_type => xs_acl.ptype_db
        )
    );
end;
ユーザーADMINにて実行します。


変更は以上です。

APEXアプリケーションについては対応は不要で、そのまま動作します。

DBMS_CLOUD.CREATE_CREDENTIALで作成したデータベース資格証明を使ってAPEXのAPEX_WEB_SERVICE.MAKE_REST_REQUESTを呼び出し、例えばAWSのBedrockやGoogleのVertex AIのAPIが呼び出せるのかと思って調査を始めたので、そういう機能ではなかったことは少々残念です。