2023年6月22日木曜日

OCIのシークレットを操作するアプリケーションを作成する(2) - シークレットの内容を操作する

 前の記事で作成したAPEXアプリケーションに、シークレットの内容を操作する機能を付加します。

APEXのWeb資格証明をシークレットとして保存します。シークレットとして保存したWeb資格証明の確認や更新をできるようにします。


RESTデータ・ソースの作成


Vault Secret Retrieval APIを呼び出すRESTデータ・ソースを作成します。

作成済みのシークレットのIdを取得します。Vault Secret Retrieval APIを呼び出す際の引数として与えます。

対話モード・レポートの鉛筆アイコンに対して、リンクのアドレスをコピーを実行し、p3_idとして渡されている値をコピーします。

javascript:apex.theme42.dialog('\u002Fords\u002Fr\u002Fapexdev\u002Fmanage-secrets\u002Fsecrets?p3_id=ocid1.vaultsecret.oc1.iad.ama****************************************************************354w6q\u0026p3_compartment_id=ocid1.tenancy.oc1..

共有コンポーネントのRESTデータ・ソースを開き、作成を開始します。手順の最初の方は、Vault Secret ManagementのRESTデータ・ソースを作成したときと同じです。

ソース・タイプとしてOracle Cloud Infrastructure(OCI)を選択し、名前はVault Secret Retrievalとします。

URLエンドポイントとして、以下を指定します。

https://secrets.vaults.us-ashburn-1.oci.oraclecloud.com/20190301/secretbundles/シークレットのOCID

次へ進みます。


リモート・サーバーとしてOCI Vault Secret Retrieval Endpoint(前の記事で作成済み)が選択されていることを確認します。

次へ進みます。


認証が必要ですをオンにし、資格証明としてOCI API Accessを選択します。

検出をクリックします。


secretIdで指定したシークレットが取得されます。

RESTデータ・ソースの作成をクリックします。


RESTデータ・ソースVault Secret Retrievalが作成されます。

編集画面を開きます。

最初にURLパス接頭辞よりsecretbundles以降の直書きされたsecretIdを削除します。

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


再度編集画面を開き、データ・プロファイルの編集をクリックします。


列SECRETIDの名前をスネークケースのSECRET_IDに変更します。主キーをYesにします。


キャメルケースのセレクタに合わせて、他の列名もスネークケースに書き換えます。

以上の変更を行い、変更の適用をクリックします。


操作の行のフェッチの編集画面を開きます。鉛筆アイコンをクリックします。


操作のURLパターンを/{secretId}とします。

パラメータの追加をクリックします。


パラメータのタイプとしてURLパターンを選択し、名前はsecretIdとします。詳細の必須をオンにします。

パラメータの追加をクリックします。


再度、パラメータの追加を開き、パラメータのタイプとしてデータ・プロファイル列を選択します。

選択できるデータ・プロファイル列を追加します。ただし、実際に使用する列はCONTENTのみです。


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


以上でRESTデータ・ソースVault Secret Retrievalは出来上がりです。

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

操作のデータベース・アクションが行のフェッチのURLパターンに、/{secretId}が設定されていることを再度確認してください。



シークレットを操作するパッケージの作成


APEXのWeb資格証明を作る情報からOCI Vaultのシークレットとして保存するデータを生成したり、その逆を行うファンクションを実装したパッケージUTL_APEX_WEB_CREDENTIAL_MANAGERを作成します。取り出したシークレットを元にAPEXのWeb資格証明を作成するプロシージャも含みます。

PL/SQLのコードは記事の末尾に添付します。

コードの実行には、SQLワークショップのSQLスクリプトが使えます。


Web資格証明の扱いを追加



フォーム・リージョンのページ・アイテムP3_CONTENTは、ボールトに保存されるシークレットにそのまま対応しています。このシークレットにAPEXのWeb資格証明の情報を含めます。

ページ・アイテムP3_CONTENTを直接扱うことは無くなるため、タイプを非表示に変更します。


Web資格証明の情報を入力するページ・アイテムを作成します。

タイプは特に指定が無ければテキスト・フィールド、ラベルはページ・アイテム名からページ番号を外し、読みやすいように変えます。セッション・ステートのストレージはすべてリクエストごと(メモリーのみ)を設定します。


ページ・アイテムP3_CREDENTIAL_NAME、P3_CREDENTIAL_STATIC_ID、P3_AUTHENTICATION_TYPEを作成します。P3_AUTHENTICATION_TYPEのLOVのタイプに静的値を選択します。

追加値の表示はオフ、NULL値の表示はオン、NULL表示値として-- Select Authentication Type --を設定します。


LOVの静的値として、以下の設定を行います。

表示値としてBasic、HTTP Header、Query Parameter、OAuth2、OCI、Secret Dataを設定し、それらの戻り値としてBASIC、HTTP_HEADER、HTTP_QUERY_STRING、OAUTH2_CLIENT_CREDENTIALS、OCI、SECRET_DATAを設定します。

実行時にソートはオフにします。


P3_AUTHENTICATION_TYPEには、APEXのWeb資格証明として設定可能なタイプを選択肢として設定しています。ただし、SECRET_DATAには対応するWeb資格証明のタイプはありません。APEXの機能に含まれていない、JWTにRS256の署名を付けるための秘密キーを保存する用途を想定しています。

選択したWeb資格証明ごとに入力可能なページ・アイテムの表示を切り替えるために、上記の選択肢に対応した静的コンテンツのリージョンを作成します。

リージョンのタイトルはLOVの表示値、外観のテンプレートはBlank with Attributesを選択します。静的IDとしてLOVの戻り値を設定します。

リージョンとしてBasic、HTTP Header、Query Parameter、OAuth2、OCI、Secret Dataを作成します。


リージョンBasicにページ・アイテムP3_USERNAME、P3_PASSWORDを作成します。

リージョンHTTP Headerにページ・アイテムP3_HEADER_NAME、P3_HEADER_VALUEを作成します。

リージョンQuery Parameterにページ・アイテムP3_PARAMETER_NAME、P3_PARAMETER_VALUEを作成します。

リージョンOAuth2にページ・アイテムP3_CLIENT_ID、P3_CLIENT_SECRET、P3_SCOPEを作成します。

リージョンOCIにページ・アイテムP3_USER_ID、P3_PRIVATE_KEY、P3_TENANCY_ID、P3_FINGERPRINTを作成します。

リージョンSecret Dataにページ・アイテムP3_SECRET_DATAを作成します。

このうち、P3_PRIVATE_KEYとP3_SECRET_DATAのタイプはテキスト領域にします。

続けてP3_ALLOWED_URLS、P3_PROMPT_ON_INSTALL、P3_CREDENTIAL_COMMENTを作成します。P3_ALLOWED_URLSとP3_CREDENTIAL_COMMENTのタイプはテキスト領域、P3_PROMPT_ON_INSTALLのタイプは切替えとします。


ページ・アイテムP3_AUTHENTICATION_TYPEの選択により、表示するページ・アイテムを切り替えるためにP3_AUTHENTICATION_TYPEに動的アクションを作成します。

識別の名前はonChange show / hideとします。タイミングのイベントはページ・アイテムのデフォルトである変更です。


TRUEアクションとしてJavaScriptコードの実行を選択し、設定のコードに以下を記述します。


初期化時に実行はオンにします。


ページ・アイテムP3_KEY_ID、P3_VAULT_ID、P3_COMPARTMENT_IDは、常にアプリケーション定義の置換文字列に設定した値にするので、これらはページ・アイテムとして非表示にします。


シークレットの名前P3_SECRET_NAMEは更新不可なので、ページ・アイテムP3_IDのアイテムがNULLでないときに読取り専用にします。


Vault Secret Retrieval APIを呼び出して、シークレットを取得します。

ヘッダーの前にプロセスを作成し、初期化フォームSecret Detailの下に配置します。

識別の名前はGet Secret、タイプはAPIの呼び出しを選択します。設定のタイプはRESTソース、RESTソースとしてVault Secret Retrieval、操作としてGET - /{secretId}を選択します。

サーバー側の条件のタイプとしてアイテムはNULLではないを選択し、アイテムとしてP3_IDを指定します。


パラメータsecretIdを選択し、値のタイプにアイテム、アイテムとしてP3_IDを指定します。


パラメータCONTENTを選択し、パラメータの出力を無視をオフに変更します。値のアイテムとしてP3_CONTENTを指定します。


以上で、ページ・アイテムP3_IDの値をsecretIdとしてVault Secret Retrieval APIが呼び出され、CONTENTとして返されたシークレットの値がページ・アイテムP3_CONTENTに設定されます。

それ以外の出力パラメータは不要なので、出力を無視をオンのままにしておきます。

取得したシークレットからWeb資格証明の値を取り出します。

ヘッダーの前にプロセスを作成し、シークレットの取り出しの下に配置します。

識別の名前はExtract Credential From Secret、タイプはAPIの呼出しを選択します。設定のタイプはPL/SQLパッケージ、パッケージとしてUTL_APEX_WEB_CREDENTIAL_MANAGERを選択します。プロシージャまたはファンクションとしてEXTRACT_CREDENTIAL_FROM_SECRETを選択します。

サーバー側の条件のタイプとしてアイテムはNULLではない、アイテムとしてP3_CONTENTを指定します。P3_CONTENTにデータが設定されている場合に限り、その値よりWeb資格証明のデータを取り出します。


パラメータp_secretを選択し、値のタイプにアイテム、アイテムとしてP3_CONTENTを指定します。これ以外のパラメータは、パラメータからページ・アイテムが自動的に選択されるようにページ・アイテム名を選んでいるため、それぞれのパラメータの値として適切なページ・アイテムが設定されています。

記述ミスなどもあり得るため、パラメータの設定は確認することを勧めます。


シークレットからWeb資格証明の値を取り出しが実装されました。反対にWeb資格証明の値よりシークレットを作成する処理を実装します。

プロセス・ビューを表示し、Web資格証明からシークレットを生成するプロセスを作成します。プロセスプロセス・フォームSecret Detailの上に配置します。

識別の名前はCreate Secret from Credential、タイプはAPIの呼出しを選択します。設定のタイプはPL/SQLパッケージ、パッケージとしてUTL_APEX_WEB_CREDENTIAL_MANAGERを選択します。プロシージャまたはファンクションとしてCREATE_SECRET_FROM_CREDENTIALを選択します。

サーバー側の条件のタイプとしてリクエストは値に含まれるを選択し、値にCREATE SAVEを指定します。ボタン作成または変更の適用を押したときに、このプロセスを実行します。


パラメータのファンクションの結果の値のアイテムにP3_CONTENTを指定します。


以上で、OCI VaultのシークレットとしてWeb資格証明を保存すること、およびシークレットからWeb資格証明のデータを取り出すことができるようになりました。

対話モード・レポートにシークレットをAPEXのWeb資格証明としてインストールするボタンを作成します。

対話モード・レポートのローカル後処理のタイプをSQL問合せに変更し、SQL問合せにインストールボタンとなる列INSTALLを追加します。



追加された列INSTALLの列の書式のHTML式に以下を記述します。このボタンをクリックしたときに、列のID(その列のシークレットのOCID)を引数にしてAPEXアクションinstall-web-credentialを呼び出します。

<button type="button" class="t-Button" data-action="install-web-credential?secretId=#ID#">Install</button>


列KEY_ID、VAULT_IDおよびCOMPARTMENT_IDといったOCIDは、あまり表示したくないため、タイプを非表示に変更します。


シークレットのOCIDを引数にしてOCI Vaultよりシークレットを取り出し、取り出したシークレットからAPEXのWeb資格証明を作成するプロセスを、Ajaxコールバックとして作成します。

識別の名前はINSTALL_WEB_CREDENTIAL、タイプはコードの実行です。ソースのPL/SQLコードとして以下を記述します。



ページ・プロパティのJavaScriptのページ・ロード時に実行に、APEXアクションのinstall-web-credentialを定義します。以下のコードを記述します。


Web資格証明をAPEXアプリケーションから作成するには、アプリケーション定義のセキュリティの詳細にある、ランタイムAPIの使用状況に含まれるワークスペース・リポジトリを変更にチェックを入れる必要があります。


以上でアプリケーションは完成です。

動作の確認を行います。

対話モード・レポートのページから作成をクリックします。

以下ではSecret Name、Credential Name、Credential Static IdはTEST_CRED01、Description、Credential CommentはテストでWeb資格証明を保存する。、Authentication TypeはBasic、Usernameはscott、Passwordはtigerとしています。

作成をクリックすると、シークレットが作成されます。


レポートに作成したシークレットが表示されます。


作成したシークレットの鉛筆アイコンをクリックし、編集ダイアログを開きます。

Username、Passwordをぞれぞれscott4、tiger4に変更し、変更の適用をクリックします。


Installを実行します。

Web資格証明の作成または更新が成功すると、成功メッセージが表示されます。


ワークスペース・ユーティリティのWeb資格証明から、作成されたWeb資格証明TEST_CRED01の内容を確認します。パスワードは表示されないため確認できませんが、その他の情報はAPEXアプリケーションで設定した値になっていることが確認できます。


以上で、作成したAPEXアプリケーションの動作確認ができました。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/manage-secrets.zip

次の記事で最後になりますが、RESTデータ・ソースを扱うアプリケーションを作成するにあたって、考慮すべき点について説明します。

続く