Oracle Database23cの新機能として、Azure ADのトークンでOracle Databaseへの認証できるようになりました。
元々Azure ADのトークンでOracleの自立型データベース「Autonomous Database」には認証できたのですが、23cの新機能としてAutonomous DatabaseだけでなくOracle Base Database,オンプレミスのOracle DatabaseでもAzure ADのトークンで認証ができるようになりました。
本機能はOracle Database23cの新機能リリースと同時に19cにもバックポートされ、19cでもご利用いただけます。
※21cではご利用いただけません。
本記事ではAzure ADのトークンでOracle Base Database23cのPDBに認証する手順を紹介します。
前提条件
- こちらのQiitaを参考に、Base DatabaseでTLS通信を有効化していること
- Azure ADのアカウントを取得していること
- Azure ADでOracle Databaseにアクセスするユーザーを作成していること
- Azure AD ドキュメントを参考に、Azure CLIをOracle Databaseのクライアントにインストールしていること
- バージョン19cまたは23cのデータベースであること
- バージョン19cのクライアントを使用していること
- Base DatabaseのあるサブネットのSecurity ListまたはNetwork Security Groupでポート443へのegress通信が許可されていること。
- Base Databaseがプライベートサブネットにある場合、NAT Gatewayが構成されていること
- その他の条件はドキュメントをご参照ください
1. Azure ADにBase Databaseをアプリとして登録する
Microsoft Azureポータルにログインし、「Azure Active Directory」を選択します。
任意のアプリケーションの名前を入力します。
「サポートされているアカウントの種類」はご利用のAzure ADの環境、ユースケースに合わせて選択してください。
リダイレクトURIは何も入力せずに登録ボタンをクリックします。
アプリケーションの登録後、概要ページに表示される「アプリケーション(クライアント)ID」を手元にコピーし、「APIの公開」ページを開きます。
「APIの公開」画面上部にある、アプリケーションIDのURI「追加」ボタンから以下URIを入力し、「保存」ボタンをクリックします。
https://<テナントのプライマリ・ドメイン>/<アプリケーション(クライアント)ID>
例)https://xxxgmail.onmicrosoft.com/92922fff-e062-45c5-9dfe-0bc888655223
テナントのプライマリ・ドメインはAzure Active Directoryの概要ページから確認できます。
続いて、同ページの「Scopeの追加」ボタンをクリックします。
スコープの追加画面では以下情報を入力し、スコープを追加します。
2. Azure ADアプリロールの作成
手順1で登録したアプリケーションの詳細画面の「アプリロール」ページを開き、「アプリロールの作成」をクリックします。
アプリロールの作成画面にて以下情報を入力し、「適用」ボタンをクリックします。
- 表示名 - 任意
- 許可されたメンバーの種類 - 「両方(ユーザー/グループ+アプリケーション」
- 値 - Oracle Databaseのロールとマッピングするロール名 例)dba_admin ※スペースは入れないでください
- 説明 - 任意
3. Databaseアプリにロールとユーザーを割り当て
Azure Active Directoryの概要ページの画面左側のメニューから「エンタープライズ アプリケーション」を選択します。
アプリケーションの概要ページのGetting Started配下にある「ユーザーとグループの割り当て」をクリックします。
ユーザーとグループの画面上部にある「ユーザーまたはグループの追加」ボタンをクリックします。
割り当ての追加画面にて、Databaseにアクセスするユーザーとロールをそれぞれ選択して「割り当て」ボタンをクリックします。
4. アプリロールにアクセス許可を付与する
Azure Active Directoryの概要ページから「アプリの登録」ページを開き、手順1で作成したDatabaseのアプリケーションを開きます。
Databaseアプリケーションの概要画面左側の「所有者」ページを開き、操作を実行しているユーザーが「所有者」として割り当てられていることを確認します。
※所有者が割り当てられていない場合は、画面上部の「所有者の追加」ボタンから操作を実行しているユーザーを手動で割り当ててください。
Databaseアプリケーション概要画面左側の「APIのアクセス許可」ページを開き、「アクセス許可の追加」ボタンをクリックします。
「自分のAPI」のタブを開き、手順1で作成したDatabaseアプリケーションを選択します。
「アプリケーションの許可」を選択し、手順2で作成したアプリロールにチェックを入れ、「アクセス許可の追加」ボタンをクリックします
APIのアクセス許可画面の「既存のディレクトリに管理者の同意を与えます」を選択し、「はい」をクリックします。
5. Base DatabaseでAzure ADによる外部認証を有効化する
Base DatabaseにSYSDBA権限でアクセスし、以下SQLコマンドで外部認証を有効化します。
#今回はPDBにアクセスするので、PDBで外部認証を有効化します。
SQL>alter session set container=<PDB名>;
SQL>ALTER SYSTEM SET IDENTITY_PROVIDER_TYPE=AZURE_AD SCOPE=BOTH;
SQL>SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME='identity_provider_type';
NAME VALUE
---------------------- -------
identity_provider_type AZURE_AD
#Azure ADの情報を登録
SQL>ALTER SYSTEM SET IDENTITY_PROVIDER_CONFIG = '{"application_id_uri" : "<手順1で設定したアプリケーションID URI>", "tenant_id" : "<テナントID>", "app_id" : "<手順1で作成したDatabaseアプリケーションのアプリケーションクライアントID>"
}' SCOPE=BOTH;
#例)
SQL>ALTER SYSTEM SET IDENTITY_PROVIDER_CONFIG = '{"application_id_uri" : "https://xxxgmail.onmicrosoft.com/92922fff-e062-45c5-9dfe-0bc888655223", "tenant_id" : "df4a6dc0-cb54-486f-a9f4-7ca3ecf170db", "app_id" : "af3ba28b-d80c-44bb-b8af-dc03601b6b42"}' SCOPE=BOTH;
テナントIDはAzure Active Directoryの概要ページから確認できます。
6. Oracle Databaseユーザーの作成とAzure ADとのマッピング
Oracle Databaseのユーザーは、直接Azure ADのユーザーとマッピング、もしくはAzure ADのアプリロールとマッピングすることができます。
また、Oracle DatabaseのロールをAzure ADのアプリロールとマッピングすることもできます。
Oracle Databaseにアクセスし、identified globally as
でマッピングするAzure ADユーザーを指定してDatabaseユーザーを作成します。
$sqlplus / as sysdba
SQL>alter session set container=<PDB名>;
SQL>CREATE USER <ユーザー名> IDENTIFIED GLOBALLY AS 'AZURE_USER=<AZURE ADユーザー名>'
#例)
SQL>CREATE USER AZUREUSER1 IDENTIFIED GLOBALLY AS 'AZURE_USER=XXX@YYYGMAIL.ONMICROSOFT.COM';
SQL>GRANT CREATE SESSION TO <ユーザー名>;
#例)
SQL>GRANT CREATE SESSION TO AZUREUSER1;
また、Oracle DatabaseのロールにAzure ADのアプリロールをマッピングことや、Oracle DatabaseのユーザーをAzure ADのアプリロールとマッピングすることもできます。
SQL>CREATE ROLE <ロール名> IDENTIFIED GLOBALLY AS 'AZURE_ROLE=<Azure ADアプリロール名>;
#例)
SQL>CREATE ROLE AZURE_DBA IDENTIFIED GLOBALLY AS 'AZURE_ROLE=dba_admin';
SQL>GRANT CREATE SESSION TO <ロール名>;
#例)
SQL>GRANT CREATE SESSION TO AZURE_DBA;
SQL>CREATE USER <ユーザー名> IDENTIFIED GLOBALLY AS 'AZURE_ROLE=<Azure ADアプリロール名>;
#例)
SQL>CREATE USER AZUREUSER2 IDENTIFIED GLOBALLY AS 'AZURE_ROLE=dba_admin';
SQL>GRANT CREATE SESSION TO <ユーザー名>;
#例)
SQL>GRANT CREATE SESSION TO AZUREUSER2;
Azure ADアプリロール名には、手順2で作成したアプリロールの「値」を入力します。
既存のユーザーをAzure ADのユーザーとマッピングしたい場合は、ALTER USERで変更します。
SQL>ALTER USER <ユーザー名> IDENTIFIED GLOBALLY AS 'AZURE_USER=<AZURE ADユーザー名>';
7. Azure ADにクライアントをアプリとして登録する
Azure Active Directoryの概要ページ、画面左側のメニューから「アプリの登録」ページを開きます。
アプリケーションの登録画面で以下情報を入力し、登録します。
- 名前 - 任意
- サポートされているアカウントの種類 - ご利用のAzure ADの環境、ユースケースに合わせて選択してください
- リダイレクトURI - 「パブリッククライアント/ネイティブ(モバイルとデスクトップ)」を選択し
http://<クライアントのIPアドレス>
を入力します。ローカルPCの場合はhttp://localhost
と入力してください。
作成したクライアントのアプリケーションの「アプリケーション(クライアント)ID」を手元にメモします。
アプリの登録画面から、手順1で登録したDatabaseのアプリケーションの「APIの公開」ページを開き、画面下部の「クライアントアプリケーションの追加」をクリックします。
クライアントIDに、登録したクライアントのアプリケーションの「アプリケーション(クライアント)ID」を入力します。
承認済みのスコープにチェックをいれ、「アプリケーションの追加」ボタンをクリックします。
8. Azure ADのトークンを取得する
Azure ADのトークンを取得します。
Azure ADのトークンを取得する方法は色々ありますが、今回はAzure CLIコマンドを使用してトークンを取得します。
Azure CLI以外の方法でトークンを使用する方法はドキュメントをご確認ください。
また、Azure CLIコマンドのインストール方法についてはこちらのドキュメントをご確認ください。
Azure CLIをインストールしたLinuxインスタンスにアクセスし、以下コマンドを実行します。
$az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code NXDZADCPA to authenticate.
コマンドの出力結果に表示されたURLとコードを手元にメモしてください。
まずはURLにブラウザでアクセスすると、コードを入力する画面が表示されます。コマンドの出力結果に表示されたコードを入力します。
続いてログインするユーザーを選択する画面が表示されます。
ここでは、手順5で作成したOracle DatabaseのユーザーとマッピングされたAzure ADユーザーを選択してください。
ユーザーが表示されない場合は、「+別のアカウントを使用する」からログインするユーザーを指定してください。
ログインできたら、「Microsoft Azure CLIにサインインしますか?」というメッセージが表示されるので、「続行」ボタンをクリックします。
Azure CLIにサインインできたらブラウザのタブを閉じます。
Linuxのクライアントのターミナルに以下のようなメッセージが表示されたらログイン成功です。
[
{
"cloudName": "AzureCloud",
"homeTenantId": "df4a6dc0-cb54-486f-a9f4-7ca3ecf170db",
"id": "e6318636-deca-404f-92de-9defbbbfe1f7",
"isDefault": true,
"managedByTenants": [],
"name": "Azure subscription 1",
"state": "Enabled",
"tenantId": "df4a6dc0-cb54-486f-a9f4-7ca3ecf170db",
"user": {
"name": "xxx@yyygmail.onmicrosoft.com",
"type": "user"
}
}
]
続いて、以下コマンドを実行しトークンを取得します。
token=$(az account get-access-token --resource=<手順1で作成したDatabaseアプリケーションのアプリケーションID URI> --query accessToken --output tsv)
#例)
token=$(az account get-access-token --resource=https://xxxgmail.onmicrosoft.com/af3ba28b-d80c-44bb-b8af-dc03601b6b42 --query accessToken --output tsv)
#取得したトークンを任意のファイル名に出力します
$echo "$token" >> token
#トークンを任意のディレクトリに保存します。今回は/test/oracle/というディレクトリに保存します。
$sudo mkdir /test/oracle/
$sudo mv token /test/oracle/
Azure CLIをインストールして初めてトークンを取得する場合は、以下のようなエラーメッセージが表示されます。
The user or administrator has not consented to use the application with ID '04b07795-8ddb-461a-bbee-02f9e1bf7b46' named 'Microsoft Azure CLI'. Send an interactive authorization request for this user and resource.
これはAzure CLIというアプリケーションが、手順1で登録したDatabaseのアプリケーションの「承認済みのクライアントアプリケーション」として登録されていないからです。
この場合は、エラーメッセージに表示されたIDを手順1で登録したDatabaseのアプリケーションの「APIの公開」から、クライアント アプリケーションに追加してください。
Azure ADのトークンの有効期限はデフォルトで1時間です。取得して1時間を経過した場合は、再度以下コマンドでトークンを取得してください。
token=$(az account get-access-token --resource=<手順1で作成したDatabaseアプリケーションのアプリケーションID URI> --query accessToken --output tsv)
9. SQL*Plusの構成
SQL*Plusコマンド実行時にトークンを使用するようにsqlnet.oraとtnsnames.oraファイルを修正します。
クライアント側のsqlnet.oraファイルを開き、以下3行を追記します。
SSL_SERVER_DN_MATCH=ON
TOKEN_AUTH=OAUTH
TOKEN_LOCATION=<トークンを保存したディレクトリ>
トークンのファイル名が「token」の場合は、tokenファイルがあるディレクトリを指定します。
トークンのファイル名が「token」以外の場合は、ファイル名を含めたディレクトリを指定します。
例)
ファイル名がtokenの場合:/test/oracle
ファイル名がazure.tokenの場合:/test/oracle/azure.token
続いて、tnsnames.oraファイルを編集し、接続詞にSSL_SERVER_CERT_dn
,TOKEN_AUTH
,TOKEN_LOCATION
を追記します。
DB23C_PDB1_tls =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCPS)(HOST = 10.0.0.231)(PORT = 1522))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = db23c_pdb1.sub09140234280.vcntest.oraclevcn.com)
)
(SECURITY =
(SSL_SERVER_CERT_dn="CN=<作成した証明書で登録したCN(PDBのサービス名)>")
(TOKEN_AUTH=OAUTH)
(TOKEN_LOCATION="<トークンを保存したディレクトリ>")
)
)
例)
DB23C_PDB1_tls =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCPS)(HOST = 10.0.0.231)(PORT = 1522))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = db23c_pdb1.sub09140234280.vcntest.oraclevcn.com)
)
(SECURITY =
(SSL_SERVER_CERT_dn="CN=db23c_pdb1.sub09140234280.vcntest.oraclevcn.com")
(TOKEN_AUTH=OAUTH)
(TOKEN_LOCATION="/test/oracle/azure.token")
)
)
10. Base Databaseのネイティブ・ネットワーク暗号化の無効化
トークンによる認証と、ネイティブ・ネットワーク暗号化(NNE)は同時に有効化することができないので、Base Databaseのsqlnet.oraを修正します。
sqlnet.oraファイルにあるSQLNET.ENCRYPTION_*
とSQLNET.CRYPTO_*
の行を全て削除します。
# ENCRYPTION_WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/opt/oracle/dcs/commonstore/wallets/tde/$ORACLE_UNQNAME)))
ENCRYPTION_WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/opt/oracle/dcs/commonstore/wallets/$ORACLE_UNQNAME/tde)))
#以下SQLNET.ENCRYPTION_*とSQLNET.CRYPTO_*で始まる行を全て削除
SQLNET.ENCRYPTION_SERVER=REQUIRED
SQLNET.CRYPTO_CHECKSUM_SERVER=REQUIRED
SQLNET.ENCRYPTION_TYPES_SERVER=(AES256,AES192,AES128)
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER=(SHA256,SHA384,SHA512,SHA1)
SQLNET.ENCRYPTION_CLIENT=REQUIRED
SQLNET.CRYPTO_CHECKSUM_CLIENT=REQUIRED
SQLNET.ENCRYPTION_TYPES_CLIENT=(AES256,AES192,AES128)
SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256,SHA384,SHA512,SHA1)
SQLNET.EXPIRE_TIME=10
11. Base Databaseにアクセスする
最後にトークンを使用してOracle Databaseにアクセスできるか動作確認します。
$sqlplus /nolog
SQL*Plus: Release 19.0.0.0.0 - Production on Mon Sep 4 04:44:11 2023
Version 19.19.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
SQL>connect /@ <PDB接続詞>
例)
SQL>connect /@DB23C_PDB1_tls
Connected.
Connectedと表示されたらAzure ADのトークンでの認証に成功です。
以下SQLで接続しているユーザー名とプロトコルも確認できます。
SQL>show user;
USER is "AZUREUSER1"
SQL>SELECT SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') FROM dual;
SYS_CONTEXT('USERENV','NETWORK_PROTOCOL')
------------------------------------------
tcps
以上の手順で、Azure ADのトークンでOracle Base Databaseにアクセスする設定は完了です。
エラーが発生した場合、例えばBase DatabaseのOSレベルでインターネット(ポート443)へのトラフィックが拒否されていないか、などネットワークの設定を見直してみてください。
また、取得したトークンは、こちらのサイトで解析することで、中身にどのような資格情報が含まれているかを確認することも可能です。正しくトークンが取得されているか、トークンの中身を確認したい場合にご利用ください。
トークンに関するエラーやBase Databaseへの接続に失敗する場合、クライアントのsqlnet.oraファイルに以下を追記することで、指定したディレクトリにトレースログを出力することが可能です。
EVENT_25701=15
DIAG_ADR_ENABLED=TRUE
ADR_BASE=<トレースログを出力するディレクトリ>
例)ADR_BASE=/oracle/oauth2/trace
sqlnet.oraで指定したディレクトリ配下にトレースログが出力されます。
KPUZLN_TOKEN_CLIENT_TRC: OCI_ATTR_TOKEN_ISBEARER is not set to TRUE.
KPUZLN_TOKEN_CLIENT_TRC: Read OAUTH token Params.
Info = TOKEN_AUTH has the value of OAUTH.
KPUZLN_TOKEN_CLIENT_TRC: Read OAUTH token Params.
TOKEN_LOCATION specified: /test/oracle/azure.token
KPUZLN_TOKEN_CLIENT_TRC: Retry read OAUTH token from file.
reason = Either /test/oracle/azure.token is not a directory, or the directory does not contain a file named "token".
file type = 3
KPUZLN_TOKEN_CLIENT_TRC: OAUTH token is successfully read from file.
KZIAMC_CLIENT_TRC= base64 decode successful
KZIAMC_CLIENT_TRC= prepare json parsing successful.
KPUZLN_TOKEN_CLIENT_TRC: JSON parse of exp is successful.
KPUZLN_TOKEN_CLIENT_TRC: Token is not expired.
KPUZLN_TOKEN_CLIENT_TRC: TCPS check passed!
reason = Protocol is TCPS which is required for token based authentication.
KPUZLN_TOKEN_CLIENT_TRC: SSL_SERVER_DN_MATCH read info!
reason = SSL_SERVER_DN_MATCH was not found in tnsnames.ora
KPUZLN_TOKEN_CLIENT_TRC: SSL_SERVER_DN_MATCH read succeeded!
reason = SSL_SERVER_DN_MATCH read from sqlnet.ora
KPUZLN_TOKEN_CLIENT_TRC: SSL_SERVER_DN_MATCH check succeeded!
reason = SSL_SERVER_DN_MATCH value is TRUE