ラベル Security の投稿を表示しています。 すべての投稿を表示
ラベル Security の投稿を表示しています。 すべての投稿を表示

2025年10月27日月曜日

Anton Schefferさんによるパスキーを使ったAPEXアプリへのサインインの実装を確認する

現在はOracle Corporationに所属されているAnton Schefferさんによる、APEXアプリケーションにパスキー認証を組み込むプラグインを使用してみます。Anton Schefferさんはas_cryptoという、RSAやAESなどの暗号ライブラリをPL/SQLで実装したすごい人です。本記事のパスキーの実装でもDBMS_CRYPTOは使用せず、AS_CRYPTOのRSAの実装を流用しています。

APEXでパスキーを使用する実装は以前から公開されていましたが、Anton Schefferさんが使いやすいようにサンプル・アプリにしてくれました。


本記事ではこのサンプル・アプリをインストールして、APEXアプリをパスキーで認証する方法を確認します。

APEX PasskeysのGitHubリポジトリより、サンプル・アプリのエクスポートをダウンロードします。f101.sqlとしてリポジトリに保存されています。サンプル・アプリはAPEX 22.2で作成されているため、アプリをインストールできるAPEXのバージョンは22.2以降になります。



f101.sqlをダウンロードした後に、これをAPEXのワークスペースにインポートします。パスキーで認証するにはHTTPSとDNSに登録された正式なホスト名が必要なため、Always FreeのAutonomous Databaseまたはorclapex.comに作成したワークスペースにアプリケーションをインストールするとよいでしょう。

アプリケーション・ビルダーを開き、インポートをクリックします。


インポートするファイルとして、先ほどGitHubよりダウンロードしたf101.sqlを選択します。ファイルタイプはデフォルトのアプリケーション、ページまたはコンポーネントのエクスポートとします。

へ進みます。


自動的に選択されているオプションは変更は不要なので、そのままアプリケーションのインストールをクリックします。

インポートしたアプリケーションの名前はDemo for Passkeysです。


サンプル・アプリDemo for Passkeysがインストールされます。必要なデータベース・オプジェクトはプラグインが必要に応じて作成するため、そのままアプリケーションの実行ができます。

今回は最初にアプリケーションの編集を開き、テーマのリフレッシュを実施します。


ページを構成する要素としては単純なものだけが使用されているため、テーマをリフレッシュしても問題は発生しません。

テーマのリフレッシュをクリックします。


テーマのリフレッシュが完了したら、アプリケーションを実行してパスキーによる認証を確認します。


サンプル・アプリケーションの説明ページが表示されます。

Macintoshで動くかどうかわからない、と記載されていますが、macOSでも動作しました。そのほかに、パスキーを使用する手順が説明されています。
  1. 最初にスキーム・タイプ公開資格証明(ユーザー名だけで認証するテスト用の認証手段)またはOracle APEXアカウントでユーザー認証をします。
  2. 1でユーザー認証したデバイスでパスキーを登録します。
  3. この後から、同じデバイスであればパスキーでユーザー認証できます。
ナビゲーション・メニューから、Registerのページを開きます。まだ、APEXアプリケーションにはサインインしていないため、右上のユーザーはnobodyになっています。


サインイン画面が開きます。

パスキーが未登録の場合は、Opendoor Sign InもしくはAPEX Account Sign Inのどちらかを実施して、アプリケーションにサインインします。

ユーザー名の入力は不要です。


今回はユーザー名を自由に決められるOpendoor Sign Inを実施します。

ユーザー名を入力し、Sign Inをクリックします。本来は初回のサインインでも、ユーザー名やパスワードの入力を要求すべきです。


スキーム・タイプ公開資格証明なので、ユーザー名が何でも、ユーザー認証に成功します。

ページにあるボタンRegisterをクリックすると、パスキーが登録されます。


私のmacOSの環境では、MacbookのTouch IDでパスキーを保存するかどうか、確認されました。


Touch IDでの指紋認証が完了すると、registeredとポップアップが表示されます。

OKをクリックしてポップアップを閉じます。


現時点ではアプリケーションは公開資格証明で認証されているので、一旦、サインアウトします。


サインアウト後、再度ナビゲーション・メニューよりRegisterを開きます。

Sign Inをクリックし、パスキーによるサインインを実施します。


MacbookではTouch IDによる認証が要求されます。

生体認証については、デバイスごとに手順は異なるでしょう。


Touch IDによる指紋認証に成功すると、パスキーを登録したユーザーでサインインが完了します。


サンプル・アプリケーションのパスキーによる認証は、以上のように動作します。

macOSのパスワード・アプリを開くと、パスキーが登録されていることが確認できます。


以下より、パスキーによる認証の実装について紹介します。

データベース・オブジェクトとしては表AS_USER_PASSKEYSとパッケージAS_PASSKEYSが作成されます。表AS_USER_PASSKEYSには、APEXのワークスペースID、アプリケーションID、サインインするユーザー名とそのユーザに紐づいたパスキーが保存されます。

AS_USER_PASSKEYSのDDLは以下です。列PASSKEYSの型はCLOBですが、JSON形式のパスキー(WebAuthn認証情報)が保存されます。
create table as_user_passkeys
  ( id number generated always as identity constraint as_user_passkeys2_pk primary key
  , workspace_id number not null
  , app_id       number not null
  , name         varchar2(4000 char) not null
  , extra        varchar2(4000 char)
  , passkeys     clob
  )
パッケージAS_PASSKEYSの定義は以下です。
create or replace package as_passkeys
is
  function get_version
  return varchar2;

  function render
    ( p_dynamic_action apex_plugin.t_dynamic_action
    , p_plugin         apex_plugin.t_plugin
    )
  return apex_plugin.t_dynamic_action_render_result;

  function ajax
    ( p_dynamic_action apex_plugin.t_dynamic_action
    , p_plugin         apex_plugin.t_plugin
    )
  return apex_plugin.t_dynamic_action_ajax_result;

  function verify_authentication( p_username varchar2 )
  return boolean;

  function passkey_authentication
    ( p_username varchar2
    , p_password varchar2
    )
  return boolean;

end as_passkeys;
パスキーによる認証は、主に動的アクションのプラグインとして作成されています。

ファンクションrenderでは、このカスタム・プラグインを組み込んだページに挿入するHTMLやJavaScriptを生成します。

ファンクションajaxは、ボタンRegisterおよびSign Inをクリックしたときに呼び出される、データベース・サーバー側の処理になります。

ファンクションpasskey_authenticationは、カスタム認証スキームの認証ファンクションとして使用します。実際はユーザー名のみを引数として、ファンクションverify_authenticationを呼び出しています。

ほとんどの実装は動的アクション・プラグインのAS Passkeyに含まれています。


動的アクション・プラグインのAS Passkeyコールバックレンダリング・プロシージャ/ファンクション名としてinit_plugin_and_renderが設定されています。

このコードは、プラグインのソースPL/SQLコードに記述されています。


ファンクションinit_plugin_and_renderでは、if init_table and init_package( p_plugin )という条件で、表AS_USER_PASSKEYSとパッケージAS_PASSKEYSの存在を確認し、それらが存在すればas_passkeys.renderを呼び出して、動的アクション(JavaScript)から呼び出すコードを生成しています。
function init_plugin_and_render
  ( p_dynamic_action apex_plugin.t_dynamic_action
  , p_plugin         apex_plugin.t_plugin
  )
return apex_plugin.t_dynamic_action_render_result
is
  l_rv apex_plugin.t_dynamic_action_render_result;
begin
  if init_table and init_package( p_plugin )
  then
    execute immediate 'begin :x := as_passkeys.render( :p1, :p2 ); end;' using out l_rv, p_dynamic_action, p_plugin;
  end if;
  return l_rv;
end init_plugin_and_render;
ファンクションinit_tableでは、動的SQLとして以下を実行して、例外が発生したらDDLを実行しています。

declare x as_user_passkeys%rowtype; begin null; end;

ビューUSER_TABLESやALL_TABLESを検索して確認するには、アクセス権限が必要だったり、オブジェクト数が多い場合は検索に時間がかかるので、このような手法は合理的です。
function init_table
return boolean
is
  e_not_declared exception;
  pragma exception_init( e_not_declared, -6550 );
begin
  begin
    execute immediate 'declare x as_user_passkeys%rowtype; begin null; end;';
  exception
    when e_not_declared then
      apex_debug.warn( 'table as_user_passkeys does not exist' );
      execute immediate '
create table as_user_passkeys
  ( id number generated always as identity constraint as_user_passkeys2_pk primary key
  , workspace_id number not null
  , app_id       number not null
  , name         varchar2(4000 char) not null
  , extra        varchar2(4000 char)
  , passkeys     clob
  )
';
      apex_debug.trace( 'table as_user_passkeys created' );
      execute immediate '
alter table as_user_passkeys
  add constraint as_user_passkeys_uk unique( workspace_id, app_id, name )
';
      apex_debug.trace( 'unique key for as_user_passkeys created' );
  end;
  execute immediate 'declare x as_user_passkeys%rowtype; begin null; end;';
  apex_debug.info( 'table as_user_passkeys exists' );
  return true;
end init_table;
パッケージAS_PASSKEYSも同じように存在確認に例外を使っています。パッケージ定義部と本体を記述したファイルは、プラグインの添付ファイルになっています。


ファンクションinit_packageではパッケージをインストールするにあたって、プラグインの添付ファイルを実行しています。そのため、静的アプリケーション・ファイルやインストール・スクリプトを別途用意する必要が無く、プラグインだけで、プラグインの実行に必要なデータベース・オブジェクトが作成されます。

ボタンRegisterまたはSign Inをクリックしたときに呼び出されるファンクションとして、パッケージAS_PASSKEYSに含まれるファンクションAJAXが呼び出されるように、コールバックAJAXプロシージャ/ファンクション名が設定されています。


ボタンRegisterSign Inの動作は、カスタム属性Usageによって切り替えています。


Usageでは、RegisterAuthenticate(値はregisterauthenticate)を選択できます。


ボタンRegisterをクリックしたときの、動的アクションAS Passkey[プラグイン]設定UsageRegisterに設定されています。つまり、パスキーの登録作業が呼び出されます。


パスキーでサインインするボタンSign In(外観がホットのボタン)をクリックしたときの、動的アクションAS Passkey[プラグイン]設定UsageAuthenticateに設定されています。つまり、パスキーによる認証作業が呼び出されます。


動的アクション・プラグインが組み込まれたページには、AS_PASSKEYS.RENDERが生成したHTML/JavaScriptが挿入されます。

apex_javascript.add_libraryにより、プラグインに含まれているファイルwebauthn.js(またはwebauthn.min.js)がページに組み込まれます。また、ボタンクリック時にファイルwebauthn.jsに記述されているファンクション_webauthnが呼び出されるように記述されています。動的アクションのattribute_01としてプラグインの設定Usageに設定したregisterまたはauthenticateが渡され、それを引数としてサーバー側のファンクションAS_PASSKEYS.AJAXが呼び出されます。
  function render
    ( p_dynamic_action apex_plugin.t_dynamic_action
    , p_plugin         apex_plugin.t_plugin
    )
  return apex_plugin.t_dynamic_action_render_result
  is
    l_result apex_plugin.t_dynamic_action_render_result;
  begin

    if apex_application.g_debug
    then
      apex_plugin_util.debug_dynamic_action
        ( p_plugin         => p_plugin
        , p_dynamic_action => p_dynamic_action
        );
    end if;

    apex_debug.trace( '%s render: %s', p_plugin.name, p_dynamic_action.attribute_01 );

    apex_javascript.add_library( p_name      => 'webauthn#MIN#'
                               , p_directory => p_plugin.file_prefix
                               , p_version => null
                               );

    l_result.attribute_01 := p_dynamic_action.attribute_01;
    l_result.attribute_02 := p_dynamic_action.attribute_02;
    l_result.attribute_03 := p_dynamic_action.attribute_03;
    l_result.attribute_04 := p_dynamic_action.attribute_04;
    l_result.ajax_identifier := apex_plugin.get_ajax_identifier;
    l_result.javascript_function := '_webauthn';

    return l_result;

  end render;
パスキーの登録と認証のフローは以上です。

最後にAPEXアプリケーションをパスキーで認証した上でセッションを継続するために、認証スキームとしてPasskeysが作成されています。


スキーム・タイプはカスタム設定認証ファンクション名としてAS_PASSKEYS.PASSKEY_AUTHENTICATIONが設定されています。


ファンクションAS_PASSKEYS.PASSKEY_AUTHENTICATION(実際はVERIFY_AUTHENTICATION)では、設定UsageAuthenticateの動的アクションで認証されたときに、AS_PASSKEYS.AJAXがAPEXコレクションに挿入した認証子の有無を確認して、認証を引き継いでいます。

パスキー自体の生成や確認については、概ねパスキーの仕様に基づいたコードがパッケージAS_PASSKEYSに含まれています。

今回の記事は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。

2025年9月1日月曜日

Oracle Database 19c EEにEntra IDでユーザー認証してReal Application Securityを適用する

更新:2026年3月27日 - 動的ロールMCPRUNTIMEの追加等

先日の記事「Oracle Database 19c EEをTLS有効にしてEntra IDでユーザー認証できるように設定する」で作成したデータベースに、Real Application Securityによる保護を構成します。記事「Entra IDで認証したMCPサーバーにReal Application Securityを適用する」と全く同じ保護を適用しますが、対象のデータベースはAutonomous AI Databaseの26aiではなく、手元の仮想マシンで実行しているOracle Database 19c EEです。そのため、セクション「管理ユーザーRASADMINの作成と各種権限の付与」の作業をオンプレミス向けに更新します。続くセクション「Real Application Securityの構成」は全く同じ作業になります。

以下よりオンプレミスのOracle Database 19c EEを対象として、Real Application Securityを構成する手順を確認します。確認する手順は、RASの管理ユーザーRASADMINを作成するまでになります。

Oracle Database 19c EEはVirtualBoxの仮想マシンで動作しています。ネットワークのポートフォワーディングを構成することにより、ホスト・マシンからポート1521および1522を宛先としてSQL*Net接続できるようにしています。SIDORCLPDBとしてORCLPDB1が作成されています。

作業はホスト・コンピュータ上で実施します。データベースへの接続にはSQLclを使用します。

ウォレットやtnsnames.oraが保存されているディレクトリを環境変数TNS_ADMINに設定したのち、作業を進めます。

export TNS_ADMIN=$PWD

tlsdb % export TNS_ADMIN=$PWD

tlsdb % 


最初に、Real Application Securityの確認に使用するHRスキーマをインストールします。サンプル・データセットをダウンロードしたのち、解凍します。

curl -OL https://github.com/oracle-samples/db-sample-schemas/archive/refs/tags/v23.3.zip
unzip -q v23.3.zip
ls db-sample-schema-23.3

tlsdb % curl -OL https://github.com/oracle-samples/db-sample-schemas/archive/refs/tags/v23.3.zip

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

100 11.6M    0 11.6M    0     0  4327k      0 --:--:--  0:00:02 --:--:-- 5171k

tlsdb % unzip -q v23.3.zip 

tlsdb % ls db-sample-schemas-23.3 

customer_orders LICENSE.txt product_media README.txt SECURITY.md

human_resources order_entry README.md sales_history

tlsdb % 


サンプル・データセットのhuman resourcesを、PDBのORCLPDB1にインストールします。human resourceのディレクトリへ移動し、インストール・スクリプトhr_install.sqlを実行します。

cd db-sample-schemas-23.3/human_resources
sql sys@localhost/orclpdb1 as sysdba
@hr_install

tlsdb % cd db-sample-schemas-23.3/human_resources

human_resources % sql sys@localhost/orclpdb1 as sysdba


SQLcl: 火 2月 17 15:50:20 2026のリリース25.4 Production


Copyright (c) 1982, 2026, Oracle.  All rights reserved.


パスワード (**********?) ******

接続先:

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.19.0.0.0


SQL> @hr_install


Thank you for installing the Oracle Human Resources Sample Schema.

This installation script will automatically exit your database session

at the end of the installation or if any error is encountered.

The entire installation will be logged into the 'hr_install.log' log file.


Enter a password for the user HR: ******


USERS             

Enter a tablespace for HR [USERS]: 

Do you want to overwrite the schema, if it already exists? [YES|no]: 

Old HR schema has been dropped.


******  Creating REGIONS table ....


Table REGIONSは作成されました。


[中略]


コミットが完了しました。



Installation verification    

____________________________ 

Verification:                


Table             provided    actual 

______________ ___________ _________ 

regions                  5         5 

countries               25        25 

departments             27        27 

locations               23        23 

employees              107       107 

jobs                    19        19 

job_history             10        10 


Thank you!                                                  

___________________________________________________________ 

The installation of the sample schema is now finished.      

Please check the installation verification output above.    

You will now be disconnected from the database.             

Thank you for using Oracle Database!                        

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.19.0.0.0から切断されました

human_resources % 


データベース・ユーザーRASADMINを作成し、最低限必要な権限を与えます。作業はユーザーSYSで実施します。

create user rasadmin identified by [パスワード];
grant create session to rasadmin;

tlsdb % sql sys@localhost/orclpdb1 as sysdba


SQLcl: 火 2月 17 15:53:23 2026のリリース25.4 Production


Copyright (c) 1982, 2026, Oracle.  All rights reserved.


パスワード (**********?) ******

接続先:

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.19.0.0.0


SQL> create user rasadmin identified by *********;


User RASADMINは作成されました。


SQL> grant create session to rasadmin;


Grantが正常に実行されました。


SQL> 


ユーザーRASADMINに、Real Application Securityを構成するために必要な権限を与えます。パッケージXS_ADMIN_CLOUD_UTILの代わりにXS_ADMIN_UTILを呼び出します。
begin
    sys.xs_admin_util.grant_system_privilege('PROVISION','RASADMIN');
    sys.xs_admin_util.grant_system_privilege('ADMIN_ANY_SEC_POLICY','RASADMIN');
end;
/

SQL> begin

  2      sys.xs_admin_util.grant_system_privilege('PROVISION','RASADMIN');

  3      sys.xs_admin_util.grant_system_privilege('ADMIN_ANY_SEC_POLICY','RASADMIN');

  4  end;

  5* /


PL/SQLプロシージャが正常に完了しました。


SQL> 


ロールHR_ROLEを作成し、ユーザーRASADMINに割り当てます。ロールHR_ROLEは後ほど、ユーザーRASADMINが作成したアプリケーション・ロールEMPLOYEEに割り当てます。
create role hr_role;
grant select on hr.departments to hr_role;
grant select on hr.employees to hr_role;
grant select on hr.jobs to hr_role;
grant select on hr.job_history to hr_role;
grant select on hr.locations to hr_role;
grant select on hr.regions to hr_role;
grant select on hr.countries to hr_role;
grant select on hr.emp_details_view to hr_role;
grant hr_role to rasadmin with admin option;

SQL> create role hr_role;


Role HR_ROLEは作成されました。


SQL> grant select on hr.departments to hr_role;


Grantが正常に実行されました。


SQL> grant select on hr.employees to hr_role;


Grantが正常に実行されました。


SQL> grant select on hr.jobs to hr_role;


Grantが正常に実行されました。


SQL> grant select on hr.job_history to hr_role;


Grantが正常に実行されました。


SQL> grant select on hr.locations to hr_role;


Grantが正常に実行されました。


SQL> grant select on hr.regions to hr_role;


Grantが正常に実行されました。


SQL> grant select on hr.countries to hr_role;


Grantが正常に実行されました。


SQL> grant select on hr.emp_details_view to hr_role;


Grantが正常に実行されました。


SQL> grant hr_role to rasadmin with admin option;


Grantが正常に実行されました。


SQL> 


MCPサーバーの接続ユーザーMCPUSERに、RASセッションを操作する権限を与えます。呼び出すパッケージはXS_ADMIN_UTILになります。
begin
    sys.xs_admin_util.grant_system_privilege('ADMINISTER_SESSION','MCPUSER');
end;
/

SQL> begin

  2      sys.xs_admin_util.grant_system_privilege('ADMINISTER_SESSION','MCPUSER');

  3  end;

  4* /


PL/SQLプロシージャが正常に完了しました。


SQL> 


Autonomous DatabaseでRASを構成したときは、ユーザーMCPUSERにスキーマHR以下のオブジェクトを検索する権限を与えていました。

grant select any table on schema hr to mcpuser;

今回はこの権限は与えません。ロールHR_ROLEはRASの動的ロールEMPLOYEEとしてRASユーザーに割り当てられるため、必ずしもユーザーMCPUSERが同じ権限を持つ必要はありません。

ユーザーMCPUSERがスキーマHRのオブジェクトを検索する権限を持たない場合、RASポリシーが適用される前は、スキーマHRのオブジェクト自体が見えません。そのため、表HR.EMPLOYEESを検索すると「ORA-00942: 表またはビューが存在しません。」が発生します。検索する権限がある場合は「行が選択されていません」が返されます。

以上でRASの管理ユーザーRASADMINが作成できました。

これ以降は記事「Entra IDで認証したMCPサーバーにReal Application Securityを適用する」の「スキーマMCPUSERの構成」および「Real Application Securityの構成」の作業を実施します。


動作確認



SQLclのMCPサーバーからOracle Database 19c EEのデータベースに接続し、Real Application Securityによる保護を確認します。

MCPサーバーからのデータベース接続をEntra IDで認証するには、TOKEN_AUTHにAZURE_DEVICE_CODEは使用できません。OAUTHかAZURE_INTERACTIVEのどちらかを設定することになりますが、AZURE_INTERACTIVEでユーザー認証するにはURLの書き換えが必要なため、今回はTOKEN_AUTH=OAUTHで接続することにします。

tnsnames.oraにTNS名として、以下のORCLPDB1_TLS_OAUTHを追記します。TOKEN_LOCATIONは、コマンドaz account get-access-tokenを実行して取り出すアクセス・トークンの保存先となるファイルを指定します。
ORCLPDB1_TLS_OAUTH =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCPS)(HOST = 0.0.0.0)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCLPDB1)
    )
    (SECURITY =
      (SSL_SERVER_DN_MATCH=TRUE)
      (SSL_SERVER_CERT_DN="CN=orcl19c")
      (TOKEN_AUTH=OAUTH)
      (TOKEN_LOCATION=/Users/________/Documents/tlsdb/token.txt)
    )
  )
azure-cli(azコマンド)を実行して、データベースへの認証に使用するアクセス・トークンを取得します。

Entra IDにサインインします。

az login --tenant "テナントID" --scope "アプリケーションIDのURI/session:scope:connect"

ブラウザのサインイン画面が開きます。以下はすでにサインイン済みだったので、アカウントの選択のみを求められています。サインインするユーザーを選択します。


サインインが完了します。


コマンドaz loginを実行したターミナルでは、サブスクリプションの選択を求められます。サブスクリプションは1つしかないので、デフォルトのサブスクリプションを選択しました。

以上で、Entra IDにサインインできました。

tlsdb % az login --tenant "********-****-****-****-************" --scope "https://_________outlook.onmicrosoft.com/********-****-****-****-************/session:scope:connect"

A web browser has been opened at https://login.microsoftonline.com/********-****-****-****-************/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.


Retrieving subscriptions for the selection...


[Tenant and subscription selection]


No     Subscription name     Subscription ID                       Tenant

-----  --------------------  ------------------------------------  ------------------------------------

[1] *  Azure subscription 1  ********-****-****-****-************  ********-****-****-****-************


The default is marked with an *; the default tenant is '********-****-****-****-************' and subscription is 'Azure subscription 1' (********-****-****-****-************).


Select a subscription and tenant (Type a number or Enter for no changes): 


Tenant: ********-****-****-****-************

Subscription: Azure subscription 1 (********-****-****-****-************)


[Announcements]

With the new Azure CLI login experience, you can select the subscription you want to use more easily. Learn more about it and its configuration at https://go.microsoft.com/fwlink/?linkid=2271236


If you encounter any problem, please open an issue at https://aka.ms/azclibug


[Warning] The login output has been updated. Please be aware that it no longer displays the full list of available subscriptions by default.


tlsdb % 


アクセス・トークンを取得します。token.txtの出力先は、ORCLPDB1_TLS_OAUTHTOKEN_LOCATIONとして指定した位置です。

az account get-access-token --scope "アプリケーションIDのURI/session:scope:connect" --query accessToken -o tsv > token.txt

tlsdb % az account get-access-token --scope "https://________outlook.onmicrosoft.com/********-****-****-****-************/session:scope:connect" --query accessToken -o tsv > token.txt

tlsdb % 


最初にSQLclからORCLPDB1_TLS_OAUTHに接続し、MCPサーバーから利用できるように接続を保存します。

sql -home $TNS_ADMIN /nolog
conn -save orclpdb1_tls_oauth -savepwd /@orclpdb1_tls_oauth
select sys_context('userenv','authentication_method') from dual;
exit

AUTHENTICATION_METHODTOKEN_GLOBALであることを確認します。

tlsdb % sql -home $TNS_ADMIN /nolog


SQLcl: 火 2月 17 16:05:44 2026のリリース25.4 Production


Copyright (c) 1982, 2026, Oracle.  All rights reserved.


SQL> conn -save orclpdb1_tls_oauth -savepwd /@orclpdb1_tls_oauth

名前: orclpdb1_tls_oauth

接続文字列: orclpdb1_tls_oauth

ユーザー: 

パスワード: 未保存

接続しました.

SQL> select sys_context('userenv','authentication_method') from dual;


SYS_CONTEXT('USERENV','AUTHENTICATION_METHOD')    

_________________________________________________ 

TOKEN_GLOBAL                                      


SQL> exit

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.19.0.0.0から切断されました

tlsdb % 


SQLclのMCPサーバーの動作確認に、MCP Inspectorを使用します。

MCP Inspectorを起動します。

npx -y @modelcontextprotocol/inspector

ブラウザにMCP Inspectorの画面が開きます。

tlsdb % npx -y @modelcontextprotocol/inspector


Starting MCP inspector...

⚙️ Proxy server listening on localhost:6277

🔑 Session token: 64ab1208c1766378438b53f8f5f00ca7bdb55bb6cbb57dd917c68bdfc164902d

   Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth


🚀 MCP Inspector is up and running at:

   http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=64ab1208c1766378438b53f8f5f00ca7bdb55bb6cbb57dd917c68bdfc164902d


🌐 Opening browser...



MCP Inspectorの画面で以下の設定を行ないます。

Transport TypeSTDIOを選択し、CommandSQLcl(コマンドとしてはsql)をフルパスで指定します。Arugmentsとして-homeに接続を保存しているディレクトリ、それに加えて-mcpオプションを設定します。

次にAdd Environment Variableをクリックし、追加されたEnvironment VariableとしてTNS_ADMINとそのディレクトリを設定します。

以上の設定を実施し、ボタンConnectをクリックしてSQLclのMCPサーバーを起動します。


MCPサーバーの起動を確認し、Toolsタブを開きます。List Toolsをクリックし、呼び出すことができるツールを取得します。


Toolsよりlist-connectionsを選択し、Run Toolをクリックします。Tool Resultに先ほど作成した接続orclpdb1_tls_oauthが含まれていることを確認します。


Toolsよりconnectを選択します。connection_nameorclpdb1_tls_oauthを記述し、Run Toolsをクリックします。

Tool ResultSuccessが返され、データベースに接続できたことを確認します。


Toolsよりrun-sqlを選択します。sqlに以下をを記述し、Run Toolsをクリックします。

select * from hr.employees

まだRASのポリシーが有効化されていず、また、データベース・ユーザーMCPUSERにスキーマHRの持つ表の参照権限を与えていないため、ORA-00942が発生します。


RASポリシーを有効化します。

Toolsよりrun-sqlclを選択します。sqlclに以下をを記述し、Run Toolsをクリックします。

exec emp_dept_ctx_pkg.init;

Tool ResultとしてSuccessが返され、プロシージャが実行されたことを確認します。


Toolsよりrun-sqlを選択します。sqlに以下をを記述し、Run Toolsをクリックします。

select employee_id, first_name, last_name, email, salary, commission_pct, manager_id, department_id from hr.employees;

RASポリシーが適用されて、DEPARTMENT_IDが60の行のみ(Entra IDで認証されたユーザーと同じ部署に所属している従業員)が返されていることを確認します。


以上でオンプレミスのOracle Database 19c EEについても、Entra IDによるユーザー認証およびReal Application Securityによる保護が適用ができることを確認しました。

Toolsよりdisconnectを選択し、Run Toolsをクリックします。データベースから切断されます。


Disconnectをクリックします。MCPサーバーとして起動しているSQLclが終了します。


今回の記事は以上になります。