2025年8月28日木曜日

オンプレミス環境のOracle DatabaseにMicrosoft Entra IDでユーザー認証して接続する

前回の記事「Oracle Database 23ai FreeでTLSでの通信を有効化する」にて、ローカルのコンテナで実行しているOracle Database 23ai Freeに、TLSで暗号化したTCPS接続をできるようにしました。TCPS接続はMicrosoft Entra IDによるユーザー認証の前提です。

本記事では、TCPS接続ができるデータベースにたいして、Entra IDでユーザー認証を行なって接続します。

Microsoft Entra IDの構成について、以下の記事で行った設定を流用します。

アプリケーションSALESADBとアプリロールMCPUSER_ROLEの作成は、以下の記事で実施しています。

SQLclのMCPサーバーのデータベース接続をMicrosoft Entra IDのOAuth2で認証する

アプリケーションSALESADB-CLIの作成は、以下の記事で実施しています。

SQLclのMCPサーバーのデータベース接続にTOKEN_AUTH=AZURE_INTERACTIVEの設定を使用する

以下より、作成済みのコンテナtlsdbに、それぞれTOKEN_AUTH=OAUTHAZURE_DEVICE_CODEAZURE_INTERACTIVEを設定して接続できることを確認します。


データベース・サーバーの構成



Entra IDを使ってユーザー認証できるように、データベース・サーバーを構成します。

作業はホスト・コンピュータに作成した作業ディレクトリtlsdb上で行ないます。ホスト上で実行するSQLclから、コンテナ内で動作しているデータベースに接続します。記事「Oracle Database 23ai FreeでTLSでの通信を有効化する」に沿って作業を実施ていると、ディレクトリtlsdbの下に、ネットワーク設定やウォレットが保存されているディレクトリとしてtns_adminが作成されています。このディレクトリを、あらかじめ環境変数TNS_ADMINに設定しておきます。

export TNS_ADMIN=/<環境依存のパス>/tlsdb/tns_admin

tlsdb % export TNS_ADMIN=/Users/**********/Documents/tlsdb/tns_admin 

tlsdb % 


SYSユーザーでFREEPDB1に接続し、identity_provider_typeを確認します。

select name, value from v$parameter where name = 'identity_provider_type';

identity_provider_typeは、未設定であればNONEになります。

tlsdb % sql sys/********@localhost/freepdb1 as sysdba



SQLcl: 木 8月 28 11:22:47 2025のリリース25.2 Production


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


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.9.0.25.07


SQL> select name, value from v$parameter where name = 'identity_provider_type';


NAME                      VALUE    

_________________________ ________ 

identity_provider_type    NONE     


SQL> 


identity_provider_typeとしてAZURE_ADを設定します。

alter system set identity_provider_type=AZURE_AD scope=both;

SQL> alter system set identity_provider_type=AZURE_AD scope=both;


Systemが変更されました。


SQL> 


 再度SELECT文を実行し、設定されたidentity_provider_typeを確認します。

SQL> select name, value from v$parameter where name = 'identity_provider_type';


NAME                      VALUE       

_________________________ ___________ 

identity_provider_type    AZURE_AD    


SQL> 


Azureのポータルから、Entra IDのアプリケーションSALESADBを開きます。

概要に表示されているアプリケーション(クライアント)IDapp_idの値になります。ディレクトリ(テナント)IDtenant_idの値になります。アプリケーションIDのURIapplication_id_uriの値になります。

これらの値をコピーし覚えておきます。


上記の値をIDENTITY_PROVIDER_CONFIGとして設定します。
alter system set identity_provider_config = 
'{
   "application_id_uri": "アプリケーション ID の URI" ,
   "tenant_id": "ディレクトリ (テナント) ID",
   "app_id": "アプリケーション (クライアント) ID"
}' scope=both;

SQL> alter system set identity_provider_config = 

  2  '{

  3     "application_id_uri": "api://c276626e-****-****-****-a87ff322acb6",

  4     "tenant_id": "3940511e-****-****-****-01b080952758",

  5     "app_id": "c276626e-****-****-****-a87ff322acb6"

  6* }' scope=both;


Systemが変更されました。


SQL> 


データベース・ユーザーMCPUSERを、Entra IDのアプリロールMCPUSER_ROLEにマップしたユーザーとして作成します。

create user mcpuser identified globally as 'AZURE_ROLE=MCPUSER_ROLE';
alter user mcpuser quota 25m on users;
grant create table, create view, create sequence, create synonym to mcpuser;
grant create session to mcpuser;

SQL> create user mcpuser identified globally as 'AZURE_ROLE=MCPUSER_ROLE';


User MCPUSERは作成されました。


SQL> alter user mcpuser quota 25m on users;


User MCPUSERが変更されました。


SQL> grant create table, create view, create sequence, create synonym to mcpuser;


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


SQL> grant create session to mcpuser;


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


SQL> 


データベース・ユーザーMCPUSERがネットワーク接続できるように、ACLを追加します。
begin
    dbms_network_acl_admin.append_host_ace(
        host => '*',
        ace => xs$ace_type(
            privilege_list => xs$name_list('connect'),
            principal_name => 'MCPUSER',
            principal_type => xs_acl.ptype_db
        )
    );
end;
/

SQL> begin

  2      dbms_network_acl_admin.append_host_ace(

  3          host => '*',

  4          ace => xs$ace_type(

  5              privilege_list => xs$name_list('connect'),

  6              principal_name => 'MCPUSER',

  7              principal_type => xs_acl.ptype_db

  8          )

  9      );

 10  end;

 11* /


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


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.9.0.25.07から切断されました

tlsdb % 


以上でデータベース・サーバーの設定は完了です。


ホスト・コンピュータの構成



コンテナで実行されているデータベースに接続できるように、ホスト・コンピュータを構成します。

ホスト・コンピュータにazure-cliをインストールします。本記事はMacbook ProのmacOSで作業を行なっているため、Homebrewでazure-cliをインストールしました。

brew install azure-cli

azure-cli 2.76.0がすでにインストールされていました。

tlsdb % brew install azure-cli

Warning: azure-cli 2.76.0 is already installed and up-to-date.

To reinstall 2.76.0, run:

  brew reinstall azure-cli

tlsdb % 


データベースへの接続にはSQLclを使用します。SQLclにSDKとしてjdbc-azureが導入されていることを確認します。

sql /nolog
sdk list

tlsdb % sql /nolog



SQLcl: 木 8月 28 11:49:08 2025のリリース25.2 Production


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


SQL> sdk list

+------------+-----------+---------+----------------------------------------------------------------------+

| SDK        | INSTALLED | VERSION | ドキュメント                                                               |

+------------+-----------+---------+----------------------------------------------------------------------+

| jdbc-oci   | いいえ       | 1.0.6   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |

| jdbc-azure | いいえ       | 1.0.6   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |

+------------+-----------+---------+----------------------------------------------------------------------+

SQL> 


jdbc-azureが未導入であれば、インストールします。

sdk install jdbc-azure

SQL> sdk install jdbc-azure

ojdbc-provider-azure SDKおよびその依存性をダウンロードしています

jdbc-azure SDKは正常にインストールされました。SQLclを再起動して変更を反映してください

SQL>


jdbc-azureがインストールされたことを確認して、SQLclを終了します。

SQL> sdk list

+------------+-----------+---------+----------------------------------------------------------------------+

| SDK        | INSTALLED | VERSION | ドキュメント                                                               |

+------------+-----------+---------+----------------------------------------------------------------------+

| jdbc-oci   | いいえ       | 1.0.6   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |

| jdbc-azure | はい        | 1.0.6   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |

+------------+-----------+---------+----------------------------------------------------------------------+

SQL> exit

tlsdb % 


以上でクライアント側のツールの準備は完了です。


OAUTHでの接続



TOKEN_AUTH=OAUTHでの接続を確認します。

tns_admin/tnsnames.oraにTNS名FREEPDB1_TLS_OAUTHを追加します。TOKEN_LOCATIONは環境に合わせて変更してください。
FREEPDB1_TLS_OAUTH =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCPS)(HOST = 0.0.0.0)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = FREEPDB1)
    )
    (SECURITY =
      (TOKEN_AUTH=OAUTH)
      (TOKEN_LOCATION=/Users/________/Documents/tlsdb/token.txt)
      (SSL_SERVER_DN_MATCH=TRUE)
      (SSL_SERVER_CERT_DN="CN=apex")
    )
  )
az loginコマンドを実行し、Entra IDでのユーザー認証を行ないます。

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

tlsdb % az login --tenant "3940511e-****-****-****-01b080952758" --scope "api://c276626e-****-****-****-a87ff322acb6/session:scope:connect"

A web browser has been opened at https://login.microsoftonline.com/3940511e-****-****-****-01b080952758/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`.



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


選択したアカウントはすでにサインイン済みだったので、アカウントを選択するとサインインは完了しました。


ターミナルでサブスクリプションの選択を求められます。サブスクリプションが1つしかないので、デフォルトを選択しています。

tlsdb % az login --tenant "3940511e-****-****-****-01b080952758" --scope "api://c276626e-****-****-****-a87ff322acb6/session:scope:connect"

A web browser has been opened at https://login.microsoftonline.com/3940511e-****-****-****-01b080952758/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  7adac3cb-****-****-****-2db0b2827b71  3940511e-****-****-****-01b080952758


The default is marked with an *; the default tenant is '3940511e-****-****-****-01b080952758' and subscription is 'Azure subscription 1' (7adac3cb-****-****-****-2db0b2827b71).


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


Tenant: 3940511e-****-****-****-01b080952758

Subscription: Azure subscription 1 (7adac3cb-****-****-****-2db0b2827b71)


[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は、FREEPDB1_TLS_OAUTHTOKEN_LOCATIONに指定した位置に作成します。

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

tlsdb % az account get-access-token --scope "api://c276626e-****-****-****-a87ff322acb6/session:scope:connect" --query accessToken -o tsv > token.txt

tlsdb % 


アクセス・トークンがtoken.txtとして保存されました。そのトークンを使用してデータベースに接続します。接続後、Entra IDによる接続情報を確認します。

sql /@freepdb1_tls_oauth
select sys_context('userenv','authentication_method'), sys_context('userenv','authenticated_identity');


tlsdb % sql /@freepdb1_tls_oauth



SQLcl: 木 8月 28 12:14:42 2025のリリース25.2 Production


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


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.9.0.25.07


SQL> select sys_context('userenv','authentication_method'), sys_context('userenv','authenticated_identity');


SYS_CONTEXT('USERENV','AUTHENTICATION_METHOD')    SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY')               

_________________________________________________ _____________________________________________________________ 

TOKEN_GLOBAL                                      yuji________outlook.com_EXT_@yuji______outlook.onmicrosoft.com    


SQL> 


データベースの接続ユーザーを確認します。

select sys_context('userenv','session_user'), sys_context('userenv','current_user');

SQL> select sys_context('userenv','session_user'), sys_context('userenv','current_user');


SYS_CONTEXT('USERENV','SESSION_USER')    SYS_CONTEXT('USERENV','CURRENT_USER')    

________________________________________ ________________________________________ 

MCPUSER                                  MCPUSER                                  


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.9.0.25.07から切断されました

tlsdb % 


以上で、TOKEN_AUTH=OAUTHでのユーザー認証が実施できていることが確認できました。


AZURE_DEVICE_CODEでの接続



Azureのポータルから、Entra IDのアプリケーションSALESADB-CLIを開きます。

概要に表示されているアプリケーション(クライアント)IDCLIENT_IDの値になります。ディレクトリ(テナント)IDTENANT_IDの値になります。AZURE_DB_APP_ID_URIの値はここにはなく、アプリケーションSALESADBアプリケーションIDのURIAZURE_DB_APP_ID_URIの値になります。

これらの値をコピーし覚えておきます。


TOKEN_AUTH=AZURE_DEVICE_CODEでの接続を確認します。

tns_admin/tnsnames.oraにTNS名FREEPDB1_TLS_CODEを追加します。TENANT_IDCLIENT_IDおよびAZURE_DB_APP_ID_URIは環境に合わせて指定します。
FREEPDB1_TLS_CODE =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCPS)(HOST = 0.0.0.0)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = FREEPDB1)
    )
    (SECURITY =
        (TOKEN_AUTH=AZURE_DEVICE_CODE)
        (TENANT_ID=ディレクトリ (テナント) ID)
        (CLIENT_ID=アプリケーション (クライアント) ID)
        (AZURE_DB_APP_ID_URI=アプリケーション ID の URI)
        (SSL_SERVER_DN_MATCH=TRUE)
        (SSL_SERVER_CERT_DN="CN=apex")
    )
  )
作成したTNS名FREEPDB1_TLS_CODEでデータベースに接続し、接続情報を確認します。

sql /@freepdb1_tls_code

tlsdb % sql /@freepdb1_tls_code



SQLcl: 木 8月 28 12:31:17 2025のリリース25.2 Production


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


To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code O6YQGTFV5 to authenticate.



表示されたメッセージに従ってブラウザを開き、コードを入力します。


アカウントはサインイン済みだったので、サインイン済みのアカウントを選択します。


サインインの確認を求められます。続行をクリックします。


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


ターミナルに戻ると、データベースへの接続が完了しています。

接続情報を確認して終了します。

select sys_context('userenv','authentication_method'), sys_context('userenv','authenticated_identity');
select sys_context('userenv','session_user'), sys_context('userenv','current_user');

SQL> select sys_context('userenv','authentication_method'), sys_context('userenv','authenticated_identity');


SYS_CONTEXT('USERENV','AUTHENTICATION_METHOD')    SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY')               

_________________________________________________ _____________________________________________________________ 

TOKEN_GLOBAL                                      yuji______outlook.com_EXT_@yuji______outlook.onmicrosoft.com    


SQL> select sys_context('userenv','session_user'), sys_context('userenv','current_user');


SYS_CONTEXT('USERENV','SESSION_USER')    SYS_CONTEXT('USERENV','CURRENT_USER')    

________________________________________ ________________________________________ 

MCPUSER                                  MCPUSER                                  


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.9.0.25.07から切断されました

tlsdb % 


以上で、TOKEN_AUTH=AZURE_DEVICE_CODEでのユーザー認証が実施できていることが確認できました。


AZURE_INTERACTIVEでの接続



TOKEN_AUTH=AZURE_INTERACTIVEでの接続を確認します。

tns_admin/tnsnames.oraにTNS名FREEPDB1_TLS_INTを追加します。TENANT_ID、CLIENT_IDおよびAZURE_DB_APP_ID_URIは、AZURE_DEVICE_CODEと同じ値を設定します。
FREEPDB1_TLS_INT =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCPS)(HOST = 0.0.0.0)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = FREEPDB1)
    )
    (SECURITY =
        (TOKEN_AUTH=AZURE_INTERACTIVE)
        (TENANT_ID=ディレクトリ (テナント) ID)
        (CLIENT_ID=アプリケーション (クライアント) ID)
        (AZURE_DB_APP_ID_URI=アプリケーション ID の URI)
        (SSL_SERVER_DN_MATCH=TRUE)
        (SSL_SERVER_CERT_DN="CN=apex")
    )
  )
作成したTNS名FREEPDB1_TLS_INTでデータベースに接続し、接続情報を確認します。

sql /@freepdb1_tls_int

tlsdb % sql /@freepdb1_tls_int    



SQLcl: 木 8月 28 12:45:32 2025のリリース25.2 Production


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



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

自動的に開かれるURLが適切ではありません。ワークアラウンドとして/organizations/となっている部分を/テナントID/に置き換えます。テナントIDはFREEPDB1_TLS_INTTENANT_IDとして設定している値です。

URLを置き換えたのちEnterを入力し、画面を再描画します。


URLのorganizationsの部分をテナントIDに置き換えた画面で、サインインするアカウントを選択します。


サインインに成功します。


ターミナルに戻ると、データベースへの接続が完了しています。

接続情報を確認して終了します。

select sys_context('userenv','authentication_method'), sys_context('userenv','authenticated_identity');
select sys_context('userenv','session_user'), sys_context('userenv','current_user');


SQL> select sys_context('userenv','authentication_method'), sys_context('userenv','authenticated_identity');


SYS_CONTEXT('USERENV','AUTHENTICATION_METHOD')    SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY')               

_________________________________________________ _____________________________________________________________ 

TOKEN_GLOBAL                                      yuji______outlook.com_EXT_@yuj______soutlook.onmicrosoft.com    


SQL> select sys_context('userenv','session_user'), sys_context('userenv','current_user');


SYS_CONTEXT('USERENV','SESSION_USER')    SYS_CONTEXT('USERENV','CURRENT_USER')    

________________________________________ ________________________________________ 

MCPUSER                                  MCPUSER                                  


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.9.0.25.07から切断されました

tlsdb % 


以上で、TOKEN_AUTH=AZURE_INTERACTIVEでのユーザー認証が実施できていることが確認できました。

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

追記


SQLclで認証エラーが発生したときに、logging.propertiesを作成して以下を記述します。
handlers = java.util.logging.ConsoleHandler
.level = FINEST
java.util.logging.ConsoleHandler.level = FINEST

# JDBC と SQLcl を詳細化
oracle.level = FINEST
oracle.jdbc.level = FINEST
oracle.dbtools.level = FINEST
環境変数JAVA_TOOL_OPTIONSとして以下を設定し、デバッグ出力を有効にします。
export JAVA_TOOL_OPTIONS="\
-Djava.util.logging.config.file=$PWD/logging.properties \
-Doracle.dbtools.debug=true \
-Doracle.jdbc.Trace=true \
-Doracle.jdbc.level=FINE"
エラーの発生した付近のログをChatGPTとかに貼って質問すると、思ったよりも適切な回答が得られます。