2025年12月15日月曜日

Oracle IAMの統合アプリにカスタム・クレームを追加しRole based JWT profileによる保護を確認する

Oracle REST Data Servicesが提供しているRole based JWT profileによるRESTモジュールの保護をOracle IAMで実施するには、ユーザーが所属しているグループの一覧を返すカスタム・クレームを作成する必要があります。

ORDSのPMのChris Hoinaさんによる以下のブログ記事では、カスタム・クレームとしてiam_groupsを作成しています。

How to Secure Oracle Database REST APIs with OCI IAM (IDCS) JSON Web Tokens and Role-Based Access Claims, Part One
https://blogs.oracle.com/database/ords-apis-iam-jwts-role-based-claims-part-one

上記の記事では、curlコマンドよりOracle IAMのREST APIを呼び出してカスタム・クレームを追加しています。調べた範囲では、Oracle IAMのカスタム・クレームを追加するユーザー・インターフェスは見つけられませんでした。

そのため、Chris Hoinaさんの記事では以下のチュートリアルを参考にして、REST APIを呼び出してカスタム・クレームを作成するように案内されています。

Using OAuth 2 to Access the REST API
https://docs.oracle.com/en-us/iaas/Content/Identity/api-getstarted/OATOAuthClientWebApp.htm

curlコマンドでは手作業による間違いも起こりやすいので、Oracle IAMの統合アプリケーションにカスタム・クレームを追加するAPEXアプリケーションを作成しました。

以下にアプリケーションのエクスポートを置いています。
https://github.com/ujnak/apexapps/blob/master/exports/oracle-iam-custom-claim.zip

このアプリケーションの使い方について説明します。

カスタム・クレームを追加するREST APIを呼び出すにあたって、このAPI呼び出しをOAuth2で認証する必要があります。そのために記事「Oracle IAMのOIDC認証にてAPEXアプリとそれから呼び出すORDSのREST APIを認証する」で作成した統合アプリケーションORDS JWT Testを流用します。

本アプリケーションではREST API呼び出しに使用するアクセス・トークンの取得に、Client Credentials Grantを使用します。そのため、統合アプリケーションORDS JWT TestOAuth構成を編集します。


クライアント構成認可に含まれるクライアント資格証明チェックします。


アプリケーション・ロールとしてIdentity Domain Administratorを割り当てます。

以上の変更を実施し、送信します。


アプリケーションoracle-iam-custom-claim.zipを、APEXワークスペースにインポートします。インポートしたAPEXアプリケーションを実行すると、以下のようなホーム・ページが表示されます。


ホーム・ページ上には、アクセス・トークンの取得カスタム・クレームの追加、作成済みのカスタム・クレームの一覧取得、指定したカスタム・クレームの削除を行うボタンがあります。

アプリケーションを実行するにあたって、アプリケーション定義置換文字列を更新します。


置換文字列G_DOMAIN_URLに、Oracle IAMの該当ドメインのドメインURLを設定します。


置換文字列G_CREDENTIALには、統合アプリケーションのクライアントIDクライアント・シークレットが設定されているWeb資格証明静的IDを設定します。Web資格証明が作成されていない場合は、新規に作成します。その際、G_CREDENTIALに設定した値を、Web資格証明静的IDに設定します。

OAuth2のトークン・エンドポイントの呼び出しに使用するWeb資格証明なので、認証タイプ基本認証を選択します。


クライアントIDクライアント・シークレットには、統合アプリケーションORDS JWT TestOAuth構成一般情報にあるクライアントIDクライアント・シークレットの値を設定します。


以上でAPEXアプリケーションの設定は完了です。

APEXアプリケーションを使って、カスタム・クレームを追加します。

ボタンGet Access Tokenをクリックすると、トークン・エンドポイントが呼び出され、レスポンスがAccess Token Responseに設定されます。


以下のコードが実行されています。

ボタンUpdate Custom Claimをクリックすると、取得されたアクセス・トークンをAuthorizationヘッダーに含め、Custom Claim Requestを送信します。Custom Claim Requestのデフォルトとして以下を設定し、iam_groupsというクレームを作成します。
{
    "schemas": [
        "urn:ietf:params:scim:schemas:oracle:idcs:CustomClaim"
    ],
    "name": "iam_groups",
    "value": "$user.groups.*.display",     
    "expression": true,
    "mode": "always",
    "tokenType": "AT",
    "allScopes": true
}
Chris Hoinaさんの記事ではスコープを定義していますが、以下ではallScopestrueを設定し、スコープの指定がなくてもカスタム・クレームiam_groupsがアクセス・トークンに含まれるようにしています。


以下のコードが実行されています。

ボタンList Custom Claimをクリックすると、作成済みのカスタム・クレームを一覧します。Custom Claim ResponseにはJSONのレスポンスをそのまま表示しています。Custom Claim Listには、カスタム・クレームの名前と(削除の際に設定する)ロケーションを一覧しています。


以下のコードが実行されています。

ボタンDelete Custom Claimをクリックすると、Custom Claim Locationに設定したロケーションのカスタム・クレームが削除されます。


以下のコードが実行されています。

以上の手順にて、Oracle IAMの統合アプリケーションにカスタム・クレームiam_groupsが追加されます。カスタム・クレームiam_groupsの値は$user.groups.*.displayなので、サインインしたユーザーが所属しているグループがiam_groupsに含まれます。

サインインするユーザーにグループとしてAdministratorsを割り当てます。


アプリケーションORDS JWT TestをOracle IAMで認証すると、アクセス・トークンにカスタム・クレームiam_groupsが含まれていることが確認できます。
  "iam_groups": [
    "Administrators"
  ],

そのためRole based JWT profileを作成する、ORDS_SECURITY.CREATE_JWT_PROFILEの引数p_role_claim_nameの値は/iam_groupsになります。

ただし、認証スキーム有効範囲よりカスタム・スコープapi://ords/myordsappを除き、標準のスコープprofileとemailだけになると、audienceの値(aud属性)がapi://ords/からデフォルトのドメインURLに変わります

カスタム・スコープを除外した場合、ORDS_SECURITY.CREATE_JWT_PROFILEを以下のように呼び出して、Role based JWT profileを作成します。
begin
    ords_security.delete_jwt_profile;
    ords_security.create_jwt_profile(
        p_issuer => 'https://identity.oraclecloud.com/'
        ,p_audience => 'ドメインURL'
        ,p_jwk_url => 'ドメインURL/admin/v1/SigningCert/jwk'
        ,p_role_claim_name => '/iam_groups'
    );
end;
/

ORDS側で、Oracle IAMのグループ名Administratorsに一致するロールを作成し、それを保護する権限(名前はAdministratorsにしていますが、権限名はIAMのグループ名に一致させる必要はありません)を作成します。
declare
    l_roles    owa.vc_arr;
    l_modules  owa.vc_arr;
    l_patterns owa.vc_arr;
begin
    ords.create_role(
        p_role_name => 'Administrators'
    );
    l_modules(1) := 'print';
    l_roles(1)   := 'Administrators';
    ords.define_privilege(
        p_privilege_name => 'Administrators',
        p_roles          => l_roles,
        p_modules        => l_modules,
        p_patterns       => l_patterns    -- no assignment
    );
end;
/

以上で、Oracle IAMの統合アプリにカスタム・クレームを追加し、Role based JWT profileによる保護を確認できました。


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

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