ノート:

OCI IAMドメインによって発行されたJWTトークンを使用した、ORDSの保護されたリソースへのアクセス

イントロダクション

Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) uses identity domains to provide identity and access management features such as authentication, Single Sign-On (SSO), and identity lifecycle management for OCI as well as for Oracle and non-Oracle applications, whether SaaS, cloud hosted, or on-premises.

Oracle REST Data Services (ORDS)は、HTTPSとOracle Databaseをブリッジします。中間層JavaアプリケーションであるORDSは、データベース管理REST API、SQL Developer Web、PL/SQL Gateway、Simple Oracle Document Access (SODA) for REST、およびOracle Databaseのデータおよびストアド・プロシージャと対話するためのRESTful Webサービスを公開する機能を提供します。

ORDSリリース23.3では、JSON Web Token (JWT)のサポートが導入されています。これらのベアラー・トークンを使用すると、ORDS開発者は、認証および認可をOAuth2準拠のアイデンティティ・プロバイダ(IdP)に委任してJWTアクセス・トークン(ORDSによって、ORDSで保護されたリソースへのアクセスを提供するために検証できる)を発行できます。

このチュートリアルでは、OCI IAMドメインによって発行されたJWTトークンを使用して、ORDS内の保護されたリソースにアクセスする方法を示します。このデモンストレーションでは、OCIでOracle Autonomous Databaseを使用します。OCIには、事前構成済でフルマネージドのORDSアプリケーションが付属しています。

次の図は、ソリューション・アーキテクチャの概要を示しています。

アーキテクチャの図

目的

前提条件

ノート: OCI IAMドメインおよびそれによって発行されたJWTトークンは、前述のすべての要件を満たします。

タスク1: データベース・スキーマのORDSの設定、APIエンドポイントの定義およびアクセス制御の構成

  1. OCIコンソールにログインし、「Oracle Database」に移動して「Autonomous Database」をクリックします。

  2. 「プロビジョニングされたAutonomous Databaseインスタンス」「データベース・アクション」「SQL」の順にクリックします。

  3. 次の問合せを実行して、JWTをサポートするORDSバージョン23.3以上があることを確認します。

    SELECT * FROM ORDS_METADATA.ORDS_VERSION;
    

    ORDSバージョン

  4. 次の問合せを実行してユーザー(ordstest)を作成し、必要な権限を割り当てます。

    CREATE USER ordstest IDENTIFIED BY "<Password>";
    GRANT CONNECT, RESOURCE TO ordstest;
    ALTER USER ordstest DEFAULT ROLE CONNECT, RESOURCE;
    
  5. 次の問合せを実行して、スキーマのORDSを有効にし、REST API機能を許可します。

    BEGIN
     ORDS_ADMIN.ENABLE_SCHEMA(
         p_enabled => TRUE,
         p_schema => 'ordstest',
         p_url_mapping_type => 'BASE_PATH',
         p_url_mapping_pattern => 'ordstest',
         p_auto_rest_auth=> FALSE
     );
    commit;
    END;
    /
    
  6. 次の問合せを実行して、ordstestスキーマにempという名前の表を作成し、サンプル・データを挿入します。

    CREATE TABLE ordstest.emp (
    EMPNO NUMBER(4,0),
    ENAME VARCHAR2(10 BYTE),
    JOB VARCHAR2(9 BYTE),
    MGR NUMBER(4,0),
    HIREDATE DATE,
    SAL NUMBER(7,2),
    COMM NUMBER(7,2),
    DEPTNO NUMBER(2,0),
    CONSTRAINT PK_EMP PRIMARY KEY (EMPNO)
    );
    
    Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7369,'SMITH','CLERK',7902,to_date('17-DEC-80','DD-MON-RR'),800,null,20);
    Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7499,'ALLEN','SALESMAN',7698,to_date('20-FEB-81','DD-MON-RR'),1600,300,30);
    Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7521,'WARD','SALESMAN',7698,to_date('22-FEB-81','DD-MON-RR'),1250,500,30);
    Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7566,'JONES','MANAGER',7839,to_date('02-APR-81','DD-MON-RR'),2975,null,20);
    Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7654,'MARTIN','SALESMAN',7698,to_date('28-SEP-81','DD-MON-RR'),1250,1400,30);
    
  7. 次の問合せを実行して、APIエンドポイントを含むORDSモジュール(demo)を定義します。

    BEGIN
      ORDS_ADMIN.DEFINE_MODULE(
         p_schema => 'ordstest',
         p_module_name => 'demo',
         p_base_path => '/demo/',
         p_items_per_page=> 1000,
         p_status => 'PUBLISHED',
         p_comments=> ''
     );
    COMMIT;
    END;
    /
    
  8. 次の問合せを実行して、特定のRESTリソースにマップするテンプレートempを定義します。

    BEGIN
     ORDS_ADMIN.DEFINE_TEMPLATE(
         p_schema => 'ordstest',
         p_module_name => 'demo',
         p_pattern => 'emp',
         p_priority => 0,
         p_etag_type => 'HASH',
         p_comments => ''
     );
    COMMIT;
    END;
    /
    
  9. 次の問合せを実行して、empのGETリクエスト・ハンドラを作成します。これにより、表empからデータを返す単純なSQL問合せが実行されます。

    BEGIN
     ORDS_ADMIN.DEFINE_HANDLER(
         p_schema => 'ordstest',
         p_module_name => 'demo',
         p_pattern => 'emp',
         p_method => 'GET',
         p_source_type => ords.source_type_collection_feed,
         p_source => 'select * from emp',
         p_items_per_page => 25,
         p_comments => ''
     );
    COMMIT;
    END;
    /
    

    emp表は、「ツール構成」で使用可能なOracle Autonomous DatabasesのORDSパブリック・アクセスURLに/ordstest/demo/empを追加することで、認証なしで表示できます。Postmanはこのチュートリアルで使用されます。

    オーダーURL

    認証なしでアクセス

  10. 次の問合せを実行して、demoモジュールを保護するための権限(privilegetest)を定義します。

    DECLARE
    L_PRIV_ROLES owa.vc_arr;
    L_PRIV_PATTERNS owa.vc_arr;
    L_PRIV_MODULES owa.vc_arr;
    BEGIN
    L_PRIV_MODULES( 1 ) := 'demo';
    ORDS_ADMIN.DEFINE_PRIVILEGE(
      P_Schema=> 'ordstest',
      P_PRIVILEGE_NAME => 'privilegetest',
      P_ROLES => L_PRIV_ROLES,
      P_PATTERNS =>  L_PRIV_PATTERNS,
      P_MODULES => L_PRIV_MODULES,
      P_LABEL => 'privilegetest',
      P_DESCRIPTION => 'Demonstrate controlling access with priviliges',
      P_COMMENTS=> ''
      );
    COMMIT;
    END;
    /
    

    demoモジュールはprivilegetest権限によって保護されているため、適切な認可がないとアクセスできません。アクセスを有効にするには、ordstestスキーマのJWTプロファイルを作成する必要があります。これにより、ORDSはJWTベアラー・トークンを検証し、デモ・モジュールなどの保護されたリソースへのアクセス権を付与できます。

タスク2: ORDS JWTプロファイルの作成

JWTプロファイルは、OAUTH.CREATE_JWT_PROFILEプロシージャを使用してREST対応スキーマ内に作成できます。ただし、定義できるJWTプロファイルはスキーマごとに1つのみです。既存のJWTプロファイルを更新するには、新しいJWTプロファイルを作成する前に削除する必要があります。

BEGIN
  OAUTH_ADMIN.DELETE_JWT_PROFILE(p_schema=>'ordstest');
  OAUTH_ADMIN.CREATE_JWT_PROFILE(
  p_schema => 'ordstest',
  p_issuer => 'https://idcs-123456789abcdefghijklmnopqrstuvw.identity.oraclecloud.com',
  p_audience => 'ords/ordstest/',
  p_jwk_url =>'https://idcs-123456789abcdefghijklmnopqrstuvw.identity.oraclecloud.com:443/admin/v1/SigningCert/jwk'
 );
COMMIT;
END;
/

このJWTプロファイルでは、発行者、オーディエンスおよびJWK URLを指定します。

OCI IAMドメインのIssuerおよびJWK URIを取得するには、次のイメージに示すように、GETリクエストをOCI IAMドメインURLに送信し、/.well-known/openid-configurationを追加します。

IAMドメイン・メタデータ

JWTプロファイル構成を確認するには、ordstestユーザーとしてログインし、次のSQL問合せを実行します。

SELECT * FROM ORDS_METADATA.USER_ORDS_JWT_PROFILE;

この問合せでは、JWTプロファイル詳細が取得され、発行者、オーディエンスおよびJWK URLが正しく構成されていることを確認します。

ORDS JWTプロファイル

JWTプロファイルを構成すると、エンド・ユーザーは、JWTプロファイルで指定されたOCI IAMドメインなどのOAuth 2.0準拠のIdPによって発行されたJWTトークンを表示することで、ORDS保護リソースにアクセスできます。JWTベアラー・トークンが正常に検証されると、ORDSは次のものを受け入れます。

タスク3: 認証なしでのOCI IAMドメイン署名証明書へのORDSアクセスの有効化

  1. OCIコンソールに移動し、「アイデンティティとセキュリティ」「アイデンティティ」に移動して、「ドメイン」をクリックします。

  2. 作業するアイデンティティ・ドメインの名前をクリックします。必要なドメインを見つけるには、コンパートメントの変更が必要になる場合があります。「設定」および「ドメイン設定」をクリックします。

  3. 「署名証明書へのアクセス」セクションで、「クライアント・アクセスの構成」を選択し、「変更の保存」をクリックします。これにより、ORDSは認証なしでアイデンティティ・ドメインの署名証明にアクセスできます。

    署名証明書

タスク4: リソース・サーバーとクライアント、JWTスコープおよびORDS権限の構成

必要なORDS権限に一致するスコープでJWTを発行するようにIdPを構成する必要があります。ORDS内のリソースが権限によって保護されている場合は、その権限名をスコープとして定義する必要があります。このスコープにより、アプリケーションはユーザーのかわりにアクセスをリクエストできます。発行されたJWTには、要求としてスコープを含める必要があります。OCI IAM OAuth2サービスを使用して認可を適用するため、いくつかのリソース・サーバーおよびクライアントを設定する必要があります。

タスク4.1: 目的のオーディエンスおよびスコープを持つリソース・サーバー・タイプの機密アプリケーションの作成

  1. 作業中のアイデンティティ・ドメインに移動し、「統合アプリケーション」をクリックします。

  2. 「アプリケーションの追加」「機密アプリケーション」を選択し、「ワークフローの起動」をクリックします。

  3. アプリケーションの「名前」(ORDS-SERVERなど)を入力し、「次へ」をクリックします。

  4. 「リソース・サーバー構成」セクションで、「このアプリケーションをリソース・サーバーとして今すぐ構成します」を選択します。

  5. JWTプロファイルに一致するプライマリ・オーディエンスおよびORDS権限に一致するスコープを使用してリソース・サーバーを構成します。

    リソース・サーバー構成

  6. 次へ」→「終了」をクリックします。

  7. アプリケーションの概要ページで、「アクティブ化」を選択し、アプリケーションのアクティブ化を確認します。機密アプリケーションがアクティブ化されます。

タスク4.2: 目的のスコープが割り当てられているクライアント・タイプの機密アプリケーションの作成

  1. 作業中のアイデンティティ・ドメインに移動し、「統合アプリケーション」をクリックします。

  2. 「アプリケーションの追加」「機密アプリケーション」を選択し、「ワークフローの起動」をクリックします。

  3. アプリケーションの「名前」(ORDS-CLIENTなど)を入力し、「次へ」をクリックします。

  4. 「Client configuration」セクションで、「Configure this application as a client now」を選択します。

  5. 「認可」セクションで、「クライアント資格証明」を選択します。

    ノート:このチュートリアルでは、「クライアント資格証明」「付与タイプ」として使用しています。ユーザー対応クライアントの認可コード・フローなど、要件に基づいて別の付与タイプを選択できます。

  6. 「クライアント・タイプ」で、「機密」を選択します。

  7. 「トークン発行ポリシー」セクションで、「認可済リソース」として「特定」を選択します。

  8. 「リソースの追加」をクリックし、「リソース」「スコープの追加」を選択します。タスク4.1で作成したリソース・サーバーに必要なスコープを選択します。たとえば、privilegetestです。

    クライアント構成

  9. 次へ」→「終了」をクリックします。

  10. 「アプリケーションの概要」ページで、「アクティブ化」を選択し、アプリケーションのアクティブ化を確認します。機密アプリケーションがアクティブ化されます。

  11. このクライアント・アプリケーションの「クライアントID」「クライアント・シークレット」をコピーします。認証にはこれらの資格証明が必要です。

タスク5: JWTベアラー・トークンを使用したORDSへのリクエストの送信

次の図に示すように、「付与タイプ」client_credentialsで、「スコープ」privilegetestのポスト・リクエストをOCI IAMドメイン・トークン・エンドポイントに送信します(Postmanを使用)。

トークン・エンド・ポイント

ノート: OCI IAMドメインからベアラー・トークンをリクエストする場合は、オーディエンスおよびスコープをスコープ・フィールドに含める必要があります。

クライアント資格証明

スコープ、発行者およびオーディエンスのJWTトークンを検証します。

JWTトークン詳細

これで、ordstestスキーマの保護されたORDSリソース(デモ・モジュール)にアクセスするには、次の図に示すように、有効なJWTベアラー・トークンを取得リクエストとともに指定します。

JWTによるアクセス

ORDSは、JWK URLから公開キーを取得し、トークンの署名を検証して、トークンを検証します。署名が有効な場合、ORDSは、iss (発行者)およびaud (オーディエンス)クレームがJWTプロファイルで定義されたクレームと一致するかどうかをチェックします。また、スコープ要求がリソースを保護する権限に対応していることも検証します。すべての条件が満たされた場合、ユーザーには保護されたリソースへのアクセス権が付与されます。

承認

その他の学習リソース

docs.oracle.com/learnの他のラボを確認するか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスしてOracle Learning Explorerになります。

製品ドキュメントについては、Oracle Help Centerを参照してください。