ORDS RESTモジュールとして作成したリモートMCPサーバーをMicrosoft Entra IDで保護します。MCP Inspectorについては記事「
Role based JWT profileで保護したORDS REST APIにMCP Inspectorでアクセスする - Microsoft Entra ID編」に記載した手順で認証できたのですが、ブラウザ版ChatGPTおよびClaude Desktopは不可でした。
以下より、ブラウザ版ChatGPTのアプリまたはClaude Desktopのカスタムコネクタとして、作成したORDS RESTモジュールをMicrosoft Entra IDのユーザーで認証してみます。
今回の設定では、アクセス・トークンをV2.0に強制します。また、別アプリケーションとしてクライアントを作成します。
手順としては、おおむね以下の記事と同じです。
SQLclのMCPサーバーのデータベース接続をMicrosoft Entra IDのOAuth2で認証する
SQLclのMCPサーバーのデータベース接続にTOKEN_AUTH=AZURE_INTERACTIVEの設定を使用するhttps://apexugj.blogspot.com/2025/08/sqlcl-mcp-with-azure-interactive.html
Microsoft Entra IDの設定
接続先となるORDS RESTモジュールに対応するアプリケーションを作成します。
規定のディレクトリよりアプリの登録を開き、新規作成を実行します。
名前はORDS MCP2とします。リダイレクトURIは省略します。リダイレクトURIはクライアントに対応するアプリケーションに作成します。
アプリケーションを登録します。
管理のAPIの公開を開き、Scopeの追加を実施します。
リモードMCPサーバーをMicrosoft Entra IDで認証する場合、リソース・サーバーは401 Unauthorizedのレスポンスを返すときにWWW-Authenticateヘッダーで、ここで作成するスコープを返す必要があります。
アプリケーションIDのURIとして、デフォルト値を設定します。
保存してから続けるをクリックします。
作成するスコープのスコープ名はmcp:connectとします。同意できるのはだれですか?として管理者とユーザーを選択します。管理者の同意の表示名、管理者の同意の説明ともに「Connect to My MCP Server」と記述します。
状態に有効を選択し、スコープの追加をクリックします。
管理の
アプリロールを開き、
アプリロールの作成をクリックします。
ロールによってORDS RESTモジュールを保護するので、ここで作成するアプリロールと同名のロールを、ORDSに作成しています。
表示名はORDS REST APIの呼び出し、許可されたメンバーの種類は両方(ユーザー/グループ+アプリケーション)を選択します。
値はORDSUsers(これがORDSのロール名になります)、説明は「ORDS REST APIの呼び出し」と記述します。
このアプリロールを有効にしますか?をチェックし、適用をクリックします。
アプリケーションORDS MCP2をEntra IDのユーザーに割り当てます。割り当てるユーザーに、作成したアプリロールORDSUsersを割り当てます。
ユーザーの割り当ては、エンタープライズアプリケーションに移動して実施します。
概要から、ローカルディレクトリのマネージドアプリケーションのリンクを開きます。
管理のユーザーとグループを開き、ユーザーまたはグループの追加をクリックします。
ユーザーの
選択されていませんをクリックし、ユーザーを割り当てます。
先ほど作成したアプリロールORDSUsersを割り当てるユーザーを選択し、
選択をクリックします。
割り当てるロール「ORDS REST APIの呼び出し」(値はORDSUsers)は、すでに選択されています。
割り当てをクリックします。
以上でユーザーにアプリロールORDSUsersが割り当てられました。
規定のディレクトリに戻り、アプリの登録を開きます。すべてのアプリケーションから、先ほど作成したORDS MCP2を開きます。
APIのアクセス許可を開き、
アクセス許可の追加をクリックします。
所属する組織で使用しているAPIを開き、ORDS MCP2を探して選択します。
アプリケーションの許可を選択します。
アクセス許可としてアプリロールORDSUsersが表示されます。このORDSUsersをチェックして、アクセス許可の追加を実行します。
アクセス許可にORDSUsersが追加されました。
アクセス許可の追加を再度クリックします。
先ほどと同様に、所属する組織で使用しているAPIを開き、ORDS MCP2を探して選択します。
今度は認可されたアクセス許可を選択し、アクセス許可として表示されたmcp:connectをチェックして、アクセス許可の追加を実行します。
以上でアクセス許可の設定ができました。
Entra IDのアクセストークンをv2に変更します。
マニュフェストを開きます。
マニュフェストに
accessTokenAcceptedVersionの設定を追加します。
Microsoft Graphアプリマニュフェストであれば"api"の下、AAD Graph アプリマニュフェストであれば、トップレベルに属性"accessTokenAcceptedVersion"があります。
この値を2に変更します。もし無い場合は属性を追加します。
"accessTokenAcceptedVersion": 2,
変更または追加後、保存します。
Entra ID v2アクセストークンでは、ユーザーの識別子となるclaimとして
upnを使用します。
トークン構成を開き、
オプションの要求の追加をクリックします。
トークンの種類に
アクセスを選択し、
要求に含まれる
upnを
チェックします。これはOAuth2.0のアクセストークンにclaimとしてupnを追加する、という作業です。
以上で
追加をクリックします。
Microsoft Graph profileのアクセス許可を有効にしますをチェックして、追加します。
必ずしも必要ではないようですが、念の為同様の操作を行い、
IDトークンについてもclaimとして
upnを
追加します。
以上でIDトークンとアクセストークンの両方に、属性としてupnが含まれるようになりました。
属性upnに設定される値を調整します。要求upnの3点メニューをクリックし、編集を実行します。
UPNの編集画面で、外部認証済みをはい、ハッシュ記号の置換をはいに設定します。
同じ作業をIDトークンとアクセストークンの両方で実施します。
以上で一旦、サーバーに対応したアプリケーションの設定は完了です。
次にクライアントに対応したアプリケーションを作成します。
規定のディレクトリの管理のアプリの登録を開き、新規登録を実行します。
作成するアプリケーションの名前はORDS MCP2 Clientとします。リダイレクトURIとして、ブラウザ版ChatGPTとClaude DesktopのURIの2つを設定する必要があるため、ここでの設定は省略します。
以上で登録します。
アプリケーション
ORDS MCP2 Clientが作成されます。
後ほどサーバー側のアプリケーション
ORDS MCP2への紐付けに使うため、
アプリケーション(クライアント)IDを
コピーしておきます。その後に、
リダイレクトURIを追加するのリンクを開きます。
リダイレクトURIの追加をクリックし、以下の2つのURIを追加します。
https://chatgpt.com/connector_platform_oauth_redirect
https://claude.ai/api/mcp/auth_callback
プラットフォームとしてWebを選択します。MCP InspectorはSPAなので、ブラウザ版ChatGPTやClaude DesktopもSPAとして扱うと勝手に考えていましたが、ChatGPTに相談したところ、
リダイレクトURIがhttps://chatgpt.comやhttps://claude.aiならWebです、とChatGPTに指摘されました。
OktaやAuth0、Oracle IAMはSPAとして設定できるので、Entra IDではWebである理由は不明です。Entra IDでの認証時にはクライアントIDに加えてクライアント・シークレットの指定も必要なので、DCRとPKCEが、ChatGPTやClaude Desktopが期待しているようには動作しないのかもしれません。
リダイレクトURIにChatGPTのリダイレクトURIを設定し、構成を実行します。
https://chatgpt.com/connector_platform_oauth_redirect
同様にClaude DesktopのリダイレクトURIを構成します。
https://claude.ai/api/mcp/auth_callback
設定を開き、パブリッククライアントフローを許可します。
パブリッククライアントフローを許可するとPKCEが実行されるため、クライアント・シークレットの指定は不要になるはずですが、そうなっていません。クライアント・シークレットが必要ということは、PKCEは実行されていないと思われるので、パブリッククライアントフローを許可する必要は無いかもしれません。
パブリッククライアントフローを許可するを有効にし、保存します。
管理の証明書とシークレットを開き、新しいクライアントシークレットを作成します。
説明に
secretと記述し、
有効期限はデフォルトの
推奨: 180 日(6ヶ月)を選択し、クライアントシークレットを
追加します。
追加された
シークレットの値(シークレットIDではない)をコピーし、保存しておきます。ChatGPTのアプリやClaude Desktopのカスタムコネクタを作成する際に使用します。
アプリの登録に戻り、アプリケーションORDS MCP2を開きます。
APIの公開を開き、クライアントアプリケーションの追加を実行します。
クライアントIDにクライアントに対応するアプリケーション
ORDS MCP2 Clientの
アプリケーション(クライアント)IDを設定します。
承認済みのスコープをチェックし、アプリケーションの追加を実行します。
承認済みのクライアント・アプリケーションとしてORDS MCP2 Clientが追加されます。
以上でEntra IDの設定は完了です。
ORDSおよびnginxの設定
以下のスクリプトを実行し、Oracle REST Data Servicesに権限
oracle.example.mcpを作成(すでに存在する場合は再定義)します。ロールとして
ORDSUsersを作成し、RESTモジュール
sampleserverを保護します。
declare
l_roles owa.vc_arr;
l_modules owa.vc_arr;
l_patterns owa.vc_arr;
begin
ords.create_role(
p_role_name => 'ORDSUsers'
);
l_modules(1) := 'sampleserver';
l_roles(1) := 'ORDSUsers';
ords.define_privilege(
p_privilege_name => 'oracle.example.mcp',
p_label => 'Priviledge for MCP',
p_roles => l_roles,
p_modules => l_modules,
p_patterns => l_patterns -- no assignment
);
end;
/
issuerがわからないため、ORDS_SECURITY.CREATE_JWT_PROFILEの実行より先に、/.well-known/以下を設定します。
nginxを実行しているインスタンスに接続します。
[opc@apex ~]$ sudo -s
[root@apex opc]#
nginxのドキュメント・ルートに移動します。
cd /usr/share/nginx/html
[root@apex opc]# cd /usr/share/nginx/html
[root@apex html]#
ディレクトリ
.well-knownを作成します。
mkdir .well-known[root@apex html]# mkdir .well-known
[root@apex html]#
以下を記述したファイルを、.well-known/oauth-protected-resourceとして作成します。
{
"resource": "アプリケーションORDS MCP2のアプリケーション(クライアント)ID",
"authorization_servers": [
"https://login.microsoftonline.com/テナントID/v2.0"
],
"scopes_supported": ["api://アプリケーションORDS MCP2のアプリケーション(クライアント)ID/mcp:connect"]
}
resourceの値は、サーバーに対応したアプリケーションORDS MCP2の概要にあるアプリケーション(クライアント)IDです。
authorization_serversはJSON配列で要素となる値は、概要のエンドポイントにある
OpenID Connectメタデータドキュメントの末尾の
/.well-known/openid-configurationを除いた部分です。
scopes_supportedはJSON配列で要素となる値は、
APIの公開にある
スコープです。
authorization_serversが認識されない場合を想定し、認可サーバーのメタデータをリソース・サーバーに配置します。
OpenID Connectメタデータドキュメントをダウンロードし、
.well-known以下に
oauth-authorization-serverとして配置します。
curl -O https://login.microsoftonline.com/********-****-****-****-************/v2.0/.well-known/openid-configuration
mv openid-configuration .well-known/oauth-authorization-server[root@apex html]# curl -O https://login.microsoftonline.com/********-****-****-****-************/v2.0/.well-known/openid-configuration
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1965 100 1965 0 0 5325 0 --:--:-- --:--:-- --:--:-- 5339
[root@apex html]# mv openid-configuration .well-known/oauth-authorization-server
[root@apex html]#
/etc/nginx/nginx.confを開き、ヘッダー情報がログに出力されるextended.logが有効になるように、access_logのコメントを変更します。
#access_log /var/log/nginx/access.log main;
access_log /var/log/nginx/extended.log extended;
#access_log /var/log/nginx/body.log body;
/etc/nginx/default.d/01-apex.confを開き、WWW-Authenticateヘッダーがスコープを返すように変更します。scope=で指定する値は、/.well-known/oauth-protected-resourceのscopes_supportedに含まれている値です。
location @ords_401 {
internal;
more_clear_headers 'WWW-Authenticate';
# The same IdP is used for all MCP servers.
#add_header WWW-Authenticate 'Bearer resource_metadata="$scheme://$host/.well-known/oauth-protected-resource"' always;
# scope for Microsoft Entra ID
add_header WWW-Authenticate 'Bearer resource_metadata="$scheme://$host/.well-known/oauth-protected-resource",scope="api://e375897b-30ea-4f7a-9437-93c50a006872/mcp:connect"' always;
# “A dedicated IdP is assigned to each MCP server.
#add_header WWW-Authenticate 'Bearer resource_metadata="$scheme://$host/.well-known/oauth-protected-resource$uri"' always;
以上の変更を実施し、nginxをリロードします。
[root@apex html]# nginx -s reload
[root@apex html]#
extended.logの出力を監視します。
tail -f /var/log/nginx/extended.log
[root@apex html]# tail -f /var/log/nginx/extended.log
ブラウザ版ChatGPTより接続してみます。
設定のアプリを開き、高度な設定のアプリを作成するを実行します。(ChatGPTが開発者モードである必要があります。)
新しいアプリの名前はMy Oracle Appとします。MCPサーバーのURLとして、ORDS REST APIのエンドポイントURLを設定します。
認証にOAuthを選択し、クライアントに対応したアプリケーションORDS MCP2 Clientのアプリケーション(クライアント)IDとクライアント・シークレットを指定します。
理解した上で、続行しますをチェックし、作成するをクリックします。
アプリの作成は失敗しますが、extended.logにアクセストークンが出力されます。
アクセストークンに含まれる属性audおよび属性issの値をコピーします。また、rolesクレームが存在し、JSON配列の要素としてアプリロールORDSUsersが含まれていることを確認します。
属性audはORDS_SECURITY.CREATE_JWT_PROFILEの引数p_audienceの値になります。属性issは引数p_issuerの値になります。
ブラウザでOpenID ConnectメタデータのURLを開き、属性jwks_uriの値をコピーします。この値は、ORDS_SECURITY.CREATE_JWT_PROFILEの引数p_jwk_urlの値になります。
これらの値を引数に与えて、ORDS_SECURITY.CREATE_JWT_PROFILEを呼び出し、JWTプロファイルを作成します。引数p_role_claim_nameには/rolesを与えます。
begin
ords_security.delete_jwt_profile;
ords_security.create_jwt_profile(
p_issuer => '属性issの値'
,p_audience => '属性audの値'
,p_jwk_url => '属性jwks_uriの値'
,p_role_claim_name => '/roles'
);
end;
/
ビューUSER_ORDS_JWT_PROFILEを検索し、設定内容を確認します。
select issuer,audience,jwk_url,role_claim_name from user_ords_jwt_profile
以上で、ORDS RESTモジュールの保護も完了です。
再度、ChatGPTでアプリを作成します。ブラウザを再起動して実施した方がよいです。
以下のように接続に成功し、リモートMCPサーバーのツールがアクションとして表示されます。ここで使用したMCPサーバーはChatGPTアプリとしての実装は行なっていないため、何かができるわけではありませんが、OAuthで認証できることは確認できました。
Claude Desktopでも、ChatGPTと同じ設定でカスタムコネクタを追加します。
追加したカスタムコネクタMy Oracle Appを連携させます。
Entra IDでの認証プロセスが完了すると、連携/連携させるというボタンが設定に変わります。
設定をクリックすると、コネクタとして利用できるツールが確認できます。
Claude DesktopのカスタムコネクタはChatGPTとは異なり、リモートMCPサーバーとして利用できるようです。
そのため、チャットから呼び出すことができました。
完