14.2.4 ユーザーの認証および認可

Oracle Graph Server (PGX)では、Oracle Databaseをアイデンティティ・マネージャとして使用します。ユーザー名およびパスワード・ベースの認証とKerberosベースの認証の両方がサポートされています。

グラフ・サーバーで実行できる操作は、Oracle Databaseで付与されているロールによって有効化される権限によって決まります。

14.2.4.1 認証にOracle Databaseを使用するための基本ステップ

このセクションで説明するステップに従うと、グラフ・サーバー(PGX)に対してユーザーを認証できます。

  1. Oracle Graph Server and Client (バージョン12.2以降)でサポートされているOracle Databaseバージョン(Autonomous Databaseを含む)を使用します。
  2. グラフ・サーバー(PGX)へのユーザー・アクセス権を付与および取り消すために、データベースに対するSYSDBAアクセス権(または自律型データベースの場合はADMINアクセス権)があることを確認します。
  3. グラフ・サーバーへのアクセス権を付与する予定のすべての既存ユーザーに、少なくとも次の権限が付与されていることを確認します。
    CREATE SESSION, CREATE TABLE
  4. グラフ・サーバーが実行されているホストからJDBCを介してデータベースにアクセスできることを確認します。
  5. SYSDBA (または自律型データベースではADMIN)として、次のプロシージャを実行し、グラフ・サーバーで必要なロールを作成します。

    ノート:

    Autonomous Database Serverlessインスタンスを使用している場合、またはオンプレミスのOracle Databaseバージョンが23aiの場合は、これらのロールが事前にインストールされているため、この手順を省略できます。
     -- This procedure creates a list of roles needed for graph.
      DECLARE
        PRAGMA AUTONOMOUS_TRANSACTION;
        role_exists EXCEPTION;
        PRAGMA EXCEPTION_INIT(role_exists, -01921);
        TYPE graph_roles_table IS TABLE OF VARCHAR2(50);
        graph_roles graph_roles_table;
      BEGIN
        graph_roles := graph_roles_table(
          'GRAPH_DEVELOPER',
          'GRAPH_ADMINISTRATOR',
          'GRAPH_USER',
          'PGX_SESSION_CREATE',
          'PGX_SERVER_GET_INFO',
          'PGX_SERVER_MANAGE',
          'PGX_SESSION_READ_MODEL',
          'PGX_SESSION_MODIFY_MODEL',
          'PGX_SESSION_NEW_GRAPH',
          'PGX_SESSION_GET_PUBLISHED_GRAPH',
          'PGX_SESSION_COMPILE_ALGORITHM',
          'PGX_SESSION_ADD_PUBLISHED_GRAPH',
          'PGX_SESSION_SET_IDLE_TIMEOUT');
        FOR elem IN 1 .. graph_roles.count LOOP
          BEGIN
            dbms_output.put_line('create_graph_roles: ' || elem || ': CREATE ROLE ' || graph_roles(elem));
            EXECUTE IMMEDIATE 'CREATE ROLE ' || graph_roles(elem);
          EXCEPTION
            WHEN role_exists THEN
              dbms_output.put_line('create_graph_roles: role already exists. continue');
            WHEN OTHERS THEN
              RAISE;
          END;
        END LOOP;
      EXCEPTION
        when others then
          dbms_output.put_line('create_graph_roles: hit error ');
          raise;
      END;
      /

    オプションで、このプロシージャは/opt/oracle/graph/scripts/create_graph_roles.sqlでも使用できます。

    ロールの詳細は、表14-4を参照してください。
  6. デフォルトの権限をロールGRAPH_DEVELOPERGRAPH_USERおよびGRAPH_ADMINISTRATORに割り当てて、複数の権限をグループ化します。

    ノート:

    Autonomous Database Serverlessインスタンスを使用している場合、またはオンプレミスのOracle Databaseバージョンが23aiの場合は、これらの権限がデフォルトで使用可能であるため、この手順を省略できます。
    -- This procedure add some grants to the graph roles.
      DECLARE
        PRAGMA AUTONOMOUS_TRANSACTION;
      BEGIN
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_CREATE TO GRAPH_ADMINISTRATOR';
        EXECUTE IMMEDIATE 'GRANT PGX_SERVER_GET_INFO TO GRAPH_ADMINISTRATOR';
        EXECUTE IMMEDIATE 'GRANT PGX_SERVER_MANAGE TO GRAPH_ADMINISTRATOR';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_CREATE TO GRAPH_DEVELOPER';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_NEW_GRAPH TO GRAPH_DEVELOPER';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_GET_PUBLISHED_GRAPH TO GRAPH_DEVELOPER';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_MODIFY_MODEL TO GRAPH_DEVELOPER';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_READ_MODEL TO GRAPH_DEVELOPER';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_SET_IDLE_TIMEOUT TO GRAPH_DEVELOPER';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_CREATE TO GRAPH_USER';
        EXECUTE IMMEDIATE 'GRANT PGX_SESSION_GET_PUBLISHED_GRAPH TO GRAPH_USER';
        BEGIN
          EXECUTE IMMEDIATE 'GRANT CREATE PROPERTY GRAPH TO GRAPH_DEVELOPER';
        EXCEPTION WHEN others then
          if sqlcode = -990 then
            mdsys.opg_log.debug('grant create property graph to graph_developer: missing privilege, continue');
          else
            raise;
          end if;
        END;
      EXCEPTION
        when others then
          dbms_output.put_line('add_graph_roles_grants: hit error ');
          raise;
      END;
      /

    オプションで、このプロシージャは/opt/oracle/graph/scripts/create_graph_roles.sqlでも使用できます。

  7. グラフ・サーバー(PGX)にアクセスする必要があるすべてのデータベース開発者にロールを割り当てます。たとえば:
    GRANT GRAPH_DEVELOPER TO <graphuser>

    <graphuser>はデータベースのユーザーです。個別の権限(PGX_の接頭辞が付いたロール)をユーザーに直接割り当てることもできます。

  8. 管理アクセス権が必要なユーザーに管理者ロールを割り当てます。たとえば:
    GRANT GRAPH_ADMINISTRATOR to <administratoruser>

    <administratoruser>は、データベースのユーザーです。

14.2.4.1.1 Oracle Databaseの権限とロール

この項では、グラフ・サーバー(PGX)を使用している場合にのみ必要なデータベース・ロールおよび権限について説明します。

表14-4 グラフ・サーバー(PGX)の使用に必要なOracle Databaseの権限およびロール

ロール このロールで有効な操作 使用者
PGX_SESSION_CREATE ServerInstance.createSession APIを使用して新しいPGXセッションを作成します。 グラフ開発者およびグラフ・ユーザー
PGX_SERVER_GET_INFO 管理APIを使用してPGXインスタンスのステータス情報を取得します。 PGXを管理するユーザー
PGX_SERVER_MANAGE (PGX_SERVER_GET_INFOを含む) 管理APIを使用してPGXインスタンスを管理して、PGXを停止または再起動します。 PGXを管理するユーザー
PGX_SESSION_NEW_GRAPH 構成ファイルを使用してデータベースからロードするか、PGQLのCREATE PROPERTY GRAPH文を使用するか、別のグラフからサブグラフを作成することにより、PGXに新しいグラフを作成します。 グラフ開発者およびグラフ・ユーザー
PGX_SESSION_GET_PUBLISHED_GRAPH 別のユーザーによってパブリック・ネームスペースに公開されたグラフを問い合せて表示します。 グラフ開発者およびグラフ・ユーザー
PGX_SESSION_ADD_PUBLISHED_GRAPH (PGX_SESSION_GET_PUBLISHED_GRAPHを含む) グラフをパブリック・ネームスペースに公開します。 グラフ開発者
PGX_SESSION_COMPILE_ALGORITHM PGXアルゴリズムAPIを使用してアルゴリズムをコンパイルします。 グラフ開発者
PGX_SESSION_READ_MODEL PgxMLを使用してMLモデルをロードおよび使用します。 グラフ開発者
PGX_SESSION_MODIFY_MODEL PgxMLを使用してMLモデルを作成、トレーニングおよび格納します。 グラフ開発者

複数のロールをグループ化するために、いくつかの追加ロールも作成されます。これらを使用すると、データベース・ユーザーに複数のロールを簡単に付与できます。これらの追加ロールの詳細は、グラフ・サーバー・ロールのデフォルト権限へのマッピングを参照してください。

ロールの追加と削除および個々のユーザーの権限の定義の説明に従って、アプリケーションに有用な追加グループを作成できます。

14.2.4.2 データベース認証のためのグラフ・サーバーの準備

インストールのpgx.confファイルを見つけます。

RPMを使用してグラフ・サーバーをインストールした場合、ファイルは/etc/oracle/graph/pgx.confにあります。

webappsパッケージを使用してTomcatまたはWebLogic Serverにデプロイする場合、pgx.confファイルは、Webアプリケーション・アーカイブ・ファイル(WARファイル)内のWEB-INF/classes/pgx.confにあります。

ヒント: Linuxでは、vimを使用すると、先に解凍しなくてもWARファイル内でファイルを直接編集できます。たとえば:
vim graph-server-webapp-<version>.war

pgx.confファイル内で、レルム・オプションのjdbc_url行を見つけます。

...
"pgx_realm": {
  "implementation": "oracle.pg.identity.DatabaseRealm",
  "options": {
    "jdbc_url": "<REPLACE-WITH-DATABASE-URL-TO-USE-FOR-AUTHENTICATION>",
    "token_expiration_seconds": 3600,
...

前のステップで構成したデータベースを指すJDBC URLにテキストを置き換えます。たとえば:

...
"pgx_realm": {
  "implementation": "oracle.pg.identity.DatabaseRealm",
  "options": {
    "jdbc_url": "jdbc:oracle:thin:@myhost:1521/myservice",
    "token_expiration_seconds": 3600,
...

次に、rootユーザーとして、またはsudoを使用して次のコマンドを実行して、グラフ・サーバーを起動します。

sudo systemctl start pgx

Autonomous Databaseに接続するためのグラフ・サーバー(PGX)の準備

Autonomous Databaseインスタンスに接続するようにグラフ・サーバー(PGX)を構成できます。

グラフ・サーバー(PGX)インスタンスがオンプレミスで実行されているか、Oracle Cloud Infrastructure (OCI)で実行されているかに関係なく、次のステップを実行してAutonomous Databaseインスタンスに接続するためのサービス名を特定し、/etc/oracle/graph/pgx.confファイルのJDBC URLを更新することができます。

  1. Oracle Cloud Infrastructure (OCI)コンソールからAutonomous Databaseインスタンスのウォレットをダウンロードして保存します。詳細は、クライアント資格証明(ウォレット)のダウンロードを参照してください。
  2. ウォレットを/etc/oracle/graph/wallets/<dbname>の新しいサブディレクトリに解凍し、次のようにグループ権限を変更します。
    sudo unzip Wallet_<dbname>.zip -d /etc/oracle/graph/wallets/<dbname>
    sudo chgrp -R oraclegraph /etc/oracle/graph/wallets/<dbname>
  3. /etc/oracle/graph/wallets/<dbname>ディレクトリのtnsnames.oraファイルから接続識別子を特定します。たとえば、エントリは次のようになります。
    graphdb_low = 
        description= (retry_count=20)(retry_delay=3)
            (address=
                (protocol=tcps)(port=1522)
                (host=adwc.example.oraclecloud.com)
            )
            (connect_data=(service_name=graphdb_low.adwc.oraclecloud.com))
            (security=(ssl_server_cert_dn="CN=adwc.example.oraclecloud.com, OU=Oracle BMCS US, O=Oracle Corporation, L=Redwood City, ST=California, C=US"))
    )

    前述の例では、graphdb_lowが接続識別子です。

  4. /etc/oracle/graph/pgx.confファイルのJDBC URLを、前のステップで特定した接続識別子と解凍したウォレット・ファイルへのディレクトリ・パスを使用して更新します。たとえば:
    ...
    "pgx_realm": {
      "implementation": "oracle.pg.identity.DatabaseRealm",
      "options": {
        "jdbc_url": "jdbc:oracle:thin:@graphdb_low?TNS_ADMIN=/etc/oracle/graph/wallets/<dbname>",
        "token_expiration_seconds": 3600,
    ...
    
  5. 最後に、次のように、グラフ・サーバーを再起動します。
    sudo systemctl restart pgx

14.2.4.3 キーストアへのデータベース・パスワードの格納

PGXでは、データベースからメモリーにデータを読み込むためにデータベース・アカウントが必要です。アカウントは、権限の低いアカウントである必要があります(グラフ・データを使用したセキュリティのベスト・プラクティスを参照)。

Oracle Databaseからグラフ・サーバー(PGX)へのグラフの読込みで説明されているように、トークンがそのデータベース・ユーザーに対して有効であるかぎり、追加の認証を指定しなくてもデータベースからグラフ・サーバーにデータを読み込むことができます。ただし、別のユーザーからグラフにアクセスする場合は、そのユーザーのパスワードが保護のためにJavaキーストア・ファイルに格納されているかぎり、それは可能です。

JDKにバンドルされたkeytoolコマンドを使用して、そのようなキーストア・ファイルをコマンドラインで生成できます。例として次のスクリプトを参照してください。

# Add a password for the 'database1' connection
keytool -importpass -alias database1 -keystore keystore.p12
# 1. Enter the password for the keystore
# 2. Enter the password for the database
 
# Add another password (for the 'database2' connection)
keytool -importpass -alias database2 -keystore keystore.p12
 
# List what's in the keystore using the keytool
keytool -list -keystore keystore.p12

Javaバージョン8以下を使用している場合は、前述の例のkeytoolコマンドに追加パラメータ-storetype pkcs12を渡す必要があります。

複数のパスワードを1つのキーストア・ファイルに格納できます。各パスワードは、指定された別名を使用して参照できます。

PGXグラフ構成ファイルの作成による、リレーショナル表からのグラフの直接ロード

次の例では、HRサンプル・データのサブセットをリレーショナル表からPGXにグラフとして直接ロードします。構成ファイルでは、頂点およびエッジ・プロバイダの概念を使用して、リレーショナル形式からグラフ形式へのマッピングを指定します。

ノート:

vertex_providersプロパティおよびedge_providersプロパティを指定すると、データがグラフの最適化表現にロードされます。

{
    "name":"hr",
    "jdbc_url":"jdbc:oracle:thin:@myhost:1521/orcl",
    "username":"hr",
    "keystore_alias":"database1",
    "vertex_id_strategy": "no_ids",
    "vertex_providers":[
        {
            "name":"Employees",
            "format":"rdbms",
            "database_table_name":"EMPLOYEES",
            "key_column":"EMPLOYEE_ID",
            "key_type": "string",
            "props":[
                {
                    "name":"FIRST_NAME",
                    "type":"string"
                },
                {
                    "name":"LAST_NAME",
                    "type":"string"
                },
                {
                    "name":"EMAIL",
                    "type":"string"
                },
                {
                    "name":"SALARY",
                    "type":"long"
                }
            ]
        },
        {
            "name":"Jobs",
            "format":"rdbms",
            "database_table_name":"JOBS",
            "key_column":"JOB_ID",
            "key_type": "string",
            "props":[
                {
                    "name":"JOB_TITLE",
                    "type":"string"
                }
            ]
        },
        {
            "name":"Departments",
            "format":"rdbms",
            "database_table_name":"DEPARTMENTS",
            "key_column":"DEPARTMENT_ID",
            "key_type": "string",
            "props":[
                {
                    "name":"DEPARTMENT_NAME",
                    "type":"string"
                }
            ]
        }
    ],
    "edge_providers":[
        {
            "name":"WorksFor",
            "format":"rdbms",
            "database_table_name":"EMPLOYEES",
            "key_column":"EMPLOYEE_ID",
            "source_column":"EMPLOYEE_ID",
            "destination_column":"EMPLOYEE_ID",
            "source_vertex_provider":"Employees",
            "destination_vertex_provider":"Employees"
        },
        {
            "name":"WorksAs",
            "format":"rdbms",
            "database_table_name":"EMPLOYEES",
            "key_column":"EMPLOYEE_ID",
            "source_column":"EMPLOYEE_ID",
            "destination_column":"JOB_ID",
            "source_vertex_provider":"Employees",
            "destination_vertex_provider":"Jobs"
        },
        {
            "name":"WorkedAt",
            "format":"rdbms",
            "database_table_name":"JOB_HISTORY",
            "key_column":"EMPLOYEE_ID",
            "source_column":"EMPLOYEE_ID",
            "destination_column":"DEPARTMENT_ID",
            "source_vertex_provider":"Employees",
            "destination_vertex_provider":"Departments",
            "props":[
                {
                    "name":"START_DATE",
                    "type":"local_date"
                },
                {
                    "name":"END_DATE",
                    "type":"local_date"
                }
            ]
        }
    ]
}

データの読取り

ここで、次のいずれかの方法を使用して、キーストアと構成ファイルの両方をPGXに渡すことにより、データベースに接続してデータを読み取るようPGXに指示できます。

  • グラフ・シェルで対話的に

    グラフ・シェルを使用している場合は、--secret_storeオプションで起動します。キーストア・パスワードを入力し、現在のセッションにキーストアをアタッチするよう要求されます。たとえば:

    cd /opt/oracle/graph
    ./bin/opg4j --secret_store /etc/my-secrets/keystore.p12
     
     enter password for keystore /etc/my-secrets/keystore.p12:
    

    シェルの内部では、通常のPGX APIを使用し、readGraphWithProperties APIに書き込んだJSONファイルを渡すことで、グラフをメモリーに読み込むことができます。

    opg4j> var graph = session.readGraphWithProperties("config.json")
    graph ==> PgxGraph[name=hr,N=215,E=415,created=1576882388130]
    
  • PGXの事前ロード済グラフとして
    サーバー管理者として、サーバー起動時にメモリーにグラフをロードするようPGXに指定できます。そのためには、/etc/oracle/graph/pgx.confにあるPGX構成ファイルを変更し、グラフ構成ファイルのパスをpreload_graphsセクションに追加します。たとえば:
    {
      ...
      "preload_graphs": [{
        "name": "hr", 
        "path": "/path/to/config.json"
      }],
      "authorization": [{
        "pgx_role": "GRAPH_DEVELOPER",
        "pgx_permissions": [{
          "preloaded_graph": "hr",
          "grant": "read"
        }]
      },	
    	....
      ]
    }
    rootユーザーとして、/etc/systemd/system/pgx.serviceにあるサービス・ファイルを編集し、ExecStartコマンドを変更してパスワードを含むキーストアの場所を指定します。
    
    ExecStart=/bin/bash start-server --secret-store /etc/keystore.p12

    ノート:

    これを機能させるため、/etc/keystore.p12をパスワードで保護しないでください。かわりに、oraclegraphユーザーのみが読取り可能なファイル・システム権限によってファイルを保護します。
    ファイルを編集したら、次を使用して変更をリロードします。
    sudo systemctl daemon-reload
    最後に、サーバーを起動します。
    sudo systemctl start pgx
  • Javaアプリケーション

    キーストアをJavaアプリケーションに登録するには、PgxSessionオブジェクトでregisterKeystore() APIを使用します。たとえば:

    import oracle.pgx.api.*;
     
    class Main {
       
      public static void main(String[] args) throws Exception {
        String baseUrl = args[0];
        String keystorePath = "/etc/my-secrets/keystore.p12";
        char[] keystorePassword = args[1].toCharArray();
        String graphConfigPath = args[2];
        ServerInstance instance = Pgx.getInstance(baseUrl);
        try (PgxSession session = instance.createSession("my-session")) {
          session.registerKeystore(keystorePath, keystorePassword);
          PgxGraph graph = session.readGraphWithProperties(graphConfigPath);
          System.out.println("N = " + graph.getNumVertices() + " E = " + graph.getNumEdges());
        }
      }
    }
    
    前述のサンプル・プログラムは、Oracle Graphクライアント・パッケージを使用してコンパイルおよび実行できます。たとえば:
    cd $GRAPH_CLIENT
    // create Main.java with above contents
    javac -cp 'lib/*' Main.java
    java -cp '.:conf:lib/*' Main http://myhost:7007 MyKeystorePassword path/to/config.json
    

グラフ・クライアント・アプリケーションのセキュア・コーディングのヒント

グラフ・クライアント・アプリケーションを作成する場合は、いずれのファイルまたはコードにもパスワードやその他のシークレットをクリア・テキストで格納しないでください。

コマンドライン引数からパスワードやその他のシークレットを受け入れないでください。かわりに、JDKからConsole.html#readPassword()を使用してください。

14.2.4.4 グラフを公開する権限の追加

グラフ・ビジュアライゼーション・アプリケーションでグラフ・サーバー(PGX)セッション内のグラフを表示するには、2つの方法があります。

ブラウザでグラフ・ビジュアライゼーション・ツールにログインすると、JShellセッションまたはアプリケーション・セッションとは異なるセッションになります。グラフ・ビジュアライゼーション・セッションで、JShellセッションまたはアプリケーション・セッションで作業しているグラフをビジュアル化するには、次の2つのステップのいずれかを実行します。

  1. PgxSession APIを使用して作業セッションのセッションIDを取得し、グラフ・ビジュアライゼーション・アプリケーションへのログイン時にそのセッションIDを使用します。これが推奨オプションです。
    opg4j> session.getId();
    $2 ==> "898bdbc3-af80-49b7-9a5e-10ace6c9071c"  //session id
    

    または

  2. PGX_SESSION_ADD_PUBLISHED_GRAPH権限を付与し、次のようにグラフを公開します。
    1. 次の文に示すように、グラフをビジュアル化するユーザーに、データベースのPGX_SESSION_ADD_PUBLISHED_GRAPHロールを付与します。
      GRANT PGX_SESSION_ADD_PUBLISHED_GRAPH TO <graphuser>
    2. 公開APIを使用してグラフをビジュアル化する準備ができたら、グラフを公開します。

    ノート:

14.2.4.5 トークンの有効期限

デフォルトでは、トークンは1時間有効です。

内部的には、グラフ・クライアントは30分未満で期限が切れるトークンを自動的に更新します。これは、データベースで資格証明を再認証することでも構成できます。デフォルトでは、トークンは最大で24回だけ自動的に更新できるため、その後は再度ログインする必要があります。

自動更新の最大数に達した場合は、GraphServer#reauthenticate (instance, "<user>", "<password>") APIを使用すると、セッション・データを失うことなく再度ログインできます。

ノート:

再認証前にセッションがタイムアウトした場合、セッション・データが失われる可能性があります。

たとえば:


opg4j> var graph = session.readGraphByName("BANK_GRAPH_VIEW",GraphSource.PG_PGQL)  // fails because token cannot be renewed anymore
opg4j> GraphServer.reauthenticate(instance, "<user>", "<password>".toCharArray()) // log in again
opg4j> var graph = session.readGraphByName("BANK_GRAPH_VIEW",GraphSource.PG_PGQL) // works now 
 

14.2.4.6 ロールおよび権限のカスタマイズ

ロールを追加および削除し、ロールの権限を指定することで、ロール・マッピングに対する権限を全面的にカスタマイズできます。ロールのかわりに個々のユーザーを認可することもできます。

このトピックでは、権限マッピングをカスタマイズする方法の例を示します。

14.2.4.6.1 APIを使用したグラフ権限のチェック

次のPGX APIメソッドを使用して、ロールおよびグラフ権限を確認できます。

表14-5 グラフ権限をチェックするためのAPI

クラス メソッド 説明
ServerInstance getPgxUsername() 現行ユーザーの名前
ServerInstance getPgxUserRoles() 現行ユーザーのロール名
ServerInstance getPgxGenericPermissions() 現行ユーザーのグラフ以外の(システム)権限:
  • Pgxシステム権限
  • ファイルの場所の権限
PgxGraph getPermission() 現行ユーザーのグラフ・インスタンスに対する権限

次に示すように、JShellのAPIを使用して、すべての権限関連の情報を取得できます。

/bin/opg4j -b "https://<host>:<port>" -u "<graphuser>"
opg4j> instance
instance ==> ServerInstance[embedded=false,baseUrl=https://<host>:<port>,serverVersion=null]
opg4j> instance.getPgxUsername()
$2 ==> "ORACLE"
opg4j> instance.getPgxUserRoles()
$3 ==> [GRAPH_DEVELOPER]
opg4j> instance.getPgxGenericPermissions()
$4 ==> [PGX_SESSION_CREATE, PGX_SESSION_READ_MODEL, PGX_SESSION_ADD_PUBLISHED_GRAPH, PGX_SESSION_NEW_GRAPH, PGX_SESSION_GET_PUBLISHED_GRAPH, PGX_SESSION_MODIFY_MODEL]
opg4j> var g = session.readGraphByName("BANK_GRAPH_VIEW", GraphSource.PG_PGQL)
g ==> PgxGraph[name=BANK_GRAPH_VIEW,N=999,E=4993,created=1688558374973]
opg4j> g.getPermission() // To get graph permissions
$9 ==> MANAGE
import oracle.pg.rdbms.*;
import java.sql.Connection;
import java.sql.Statement;
import oracle.pg.rdbms.pgql.PgqlConnection;
import oracle.pg.rdbms.pgql.PgqlStatement;
import oracle.pgx.api.*;
import oracle.ucp.jdbc.PoolDataSourceFactory;
import oracle.ucp.jdbc.PoolDataSource;
import java.nio.file.Files;
import java.nio.file.Path;

/**
 * This example shows how to get all permissions.
 */
public class GetPermissions
{

  public static void main(String[] args) throws Exception
  {
    int idx=0;
    String host               = args[idx++]; 
    String port               = args[idx++]; 
    String sid                = args[idx++]; 
    String user               = args[idx++]; 
    String password           = args[idx++];
    String graph              = args[idx++];
        
    Connection conn = null;
    PgxPreparedStatement stmt = null;
  
    try {
      
      // Get a jdbc connection
      PoolDataSource  pds = PoolDataSourceFactory.getPoolDataSource();
      pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
      pds.setURL("jdbc:oracle:thin:@"+host+":"+port +"/"+sid);
      pds.setUser(user);
      pds.setPassword(password);     
      conn = pds.getConnection();
      conn.setAutoCommit(false);
      
      ServerInstance instance = GraphServer.getInstance("http://localhost:7007", user, password.toCharArray());
      PgxSession session = instance.createSession("my-session");

      var statement = Files.readString(Path.of("/media/sf_Linux/Java/create-pg.pgql"));
      stmt = session.preparePgql(statement);
      stmt.execute();

      PgxGraph g = session.getGraph(graph);
      System.out.println("Graph: "+ g);
      
      String userName = instance.getPgxUsername();
      var userRoles = instance.getPgxUserRoles();
      var genericPermissions = instance.getPgxGenericPermissions();
      String graphPermission = g.getPermission().toString();

      System.out.println("Username is " + userName);
      System.out.println("User Roles are " + userRoles);
      System.out.println("Generic permissions are " + genericPermissions);
      System.out.println("Graph permission is " + graphPermission);

    }

    finally {
      // close the sql statment
      if (stmt != null) {
        stmt.close();
      }
      // close the connection
      if (conn != null) {
        conn.close();
      }
    }
  }
}

実行すると、コードの出力は次のようになります。

Graph: PgxGraph[name=BANK_GRAPH_PG,N=1000,E=5001,created=1625731370402]
Username is ORACLE
User Roles are [GRAPH_DEVELOPER]
Generic permissions are [PGX_SESSION_MODIFY_MODEL, PGX_SESSION_CREATE, PGX_SESSION_NEW_GRAPH, PGX_SESSION_READ_MODEL, PGX_SESSION_ADD_PUBLISHED_GRAPH, PGX_SESSION_GET_PUBLISHED_GRAPH]
Graph permission is MANAGE

14.2.4.6.2 ロールの追加と削除

認可リストを変更することで、新しいロール権限マッピングを追加したり、既存のマッピングを削除できます。

たとえば:


CREATE ROLE MY_CUSTOM_ROLE_1
GRANT PGX_SESSION_CREATE TO MY_CUSTOM_ROLE1 
GRANT PGX_SERVER_GET_INFO TO MY_CUSTOM_ROLE1 
GRANT MY_CUSTOM_ROLE1 TO SCOTT

14.2.4.6.3 個々のユーザーの権限の定義

ロールの権限の定義に加えて、個々のユーザーの権限を定義できます。

たとえば:

GRANT PGX_SESSION_CREATE TO SCOTT 
GRANT PGX_SERVER_GET_INFO TO SCOTT 

14.2.4.6.4 カスタム・グラフ・アルゴリズムを使用する権限の定義

開発者がカスタム・グラフ・アルゴリズムをコンパイルできるよう、権限を定義できます。

たとえば、
  1. 次の静的権限を権限のリストに追加します。
    GRANT PGX_SESSION_COMPILE_ALGORITHM TO GRAPH_DEVELOPER

14.2.4.7 グラフ・サーバーへのアクセス権の取消し

ユーザーがグラフ・サーバーにアクセスできることを取り消すには、pgx.confファイルでアクセス・ルールを定義した方法に応じて、データベースからユーザーを削除するか、ユーザーから対応するロールを取り消します。

たとえば:

REVOKE graph_developer FROM scott

グラフの権限の取消し

グラフに対するMANAGE権限を持っている場合は、PgxGraph#revokePermission APIを使用して、ユーザーまたはロールからグラフ・アクセス権を取り消すことができます。たとえば:

PgxGraph g = ...
g.revokePermission(new PgxRole("GRAPH_DEVELOPER")) // revokes previously granted role access
g.revokePermission(new PgxUser("SCOTT")) // revokes previously granted user access

14.2.4.8 カスタム認可ルールの例

開発者にカスタム認可ルールを定義できます。

例14-1 開発者にグラフの公開を許可

他のユーザーとのグラフの共有は、可能な場合にはOracle Databaseで行ってください。データベース表でGRANT文を使用して、他のユーザーが表からグラフを作成できるようにします。

グラフ・サーバー(PGX)では、次の権限を使用して、すでにメモリー内にあるグラフをグラフ・サーバーに接続している他のユーザーと共有できます。

表14-6 許可された権限

権限 この権限によって有効になる操作
READ
  • PGX APIを介して、またはPGXのPGQL問合せでグラフを読み取り、サブグラフを作成するか、グラフをクローニングします
MANAGE
  • グラフまたはスナップショットを公開します
  • READおよびEXPORTが含まれます
  • グラフに対するREADおよびEXPORT権限を付与または取り消します
EXPORT
  • グラフをファイルにエクスポートします。
  • READ権限が含まれます。

グラフの作成者は、グラフに付与されたMANAGE権限を自動的に取得します。MANAGE権限を持っている場合は、グラフに対するREADまたはEXPORT権限を他のロールまたはユーザーに付与できます。グラフには、MANAGEを付与できません。次に、グラフに対するREAD権限をuserAによってGRAPH_DEVELOPERロールに付与する例を示します。

import oracle.pgx.api.*;
import oracle.pgx.common.auth.*;
...
PgxSession session = GraphServer.getInstance("<base-url>", "<userA>", "<password-of-userA").createSession("userA");
PgxGraph g = session.readGraphByName("SAMPLE_GRAPH", GraphSource.PG_PGQL);
g.grantPermission(new PgxRole("GRAPH_DEVELOPER"), PgxResourcePermission.READ);
g.publish();
これで、次のuserBの例に示すように、GRAPH_DEVELOPERロールを持つ他のユーザーがこのグラフにアクセスし、そのグラフに対するREADアクセス権を持つことができます。
PgxSession session = GraphServer.getInstance("<base-url>", "<userB>", "<password-of-userB").createSession("userB")
PgxGraph g = session.getGraph("sample_graph")
g.queryPgql("select count(*) from match (v)").print().close()

同様に、次の例に示すように、グラフはロールではなく個々のユーザーと共有できます。

g.grantPermission(new PgxUser("OTHER_USER"), PgxResourcePermission.EXPORT)

OTHER_USERは、グラフgに対するEXPORT権限を受け取るユーザーのユーザー名です。

例14-2 開発者に事前ロード済グラフへのアクセスを許可

開発者が事前にロードされたグラフ(グラフ・サーバーの起動時にロードされたグラフ)にアクセスできるようにするには、pgx.confファイルで事前にロードされたグラフに対する読取り権限を付与します。たとえば:

"preload_graphs": [{
  "path": "/data/my-graph.json",
  "name": "global_graph"
}],
"authorization": [{
  "pgx_role": "GRAPH_DEVELOPER",
  "pgx_permissions": [{
    "preloaded_graph": "global_graph"
    "grant": "read"
  },
...

READ、EXPORTまたはMANAGE権限を付与できます。

例14-3 開発者によるローカル・ファイル・システムへのアクセスの許可

開発者が(グラフ・サーバーが実行されている)ローカル・ファイル・システムにアクセスできるようにするには、まずディレクトリを宣言してから、それを読取り権限または書込み権限にマップする必要があります。たとえば:

CREATE OR REPLACE DIRECTORY pgx_file_location AS '/opt/oracle/graph/data'
GRANT READ ON DIRECTORY pgx_file_location TO GRAPH_DEVELOPER

同様に、GRANT WRITEを使用して別の権限を追加し、書込みアクセスを許可できます。グラフをエクスポートするには、このような書込みアクセス権が必要です。

前述の構成に加えて、グラフ・サーバー・プロセスを実行するオペレーティング・システム・ユーザーには、これらのディレクトリへの実際の読取りまたは書込みに対応するディレクトリ権限が必要です。

例14-4 Autonomous Database上のディレクトリへのアクセスを許可

開発者がOracle Autonomous Databaseのファイルから読取りおよび書込みできるようにするには、次のステップを実行する必要があります。

  1. SQLベースのOracle Databaseツールのいずれかを使用するか、Webベースの組込みインタフェースであるデータベース・アクションを使用して、ADMINユーザーとしてAutonomous Databaseインスタンスに接続します。
  2. 次のように、graph:接頭辞を使用してディレクトリへのパスを指定して、ディレクトリを作成します。
    CREATE OR REPLACE DIRECTORY pgx_file_location AS 'graph:/opt/oracle/graph/data'
  3. 目的のロールにディレクトリに対する読取り権限または書込み権限を付与します。たとえば:
    GRANT READ ON DIRECTORY pgx_file_location TO GRAPH_DEVELOPER

14.2.4.9 グラフ・サーバー(PGX)に対するKerberos対応の認証

グラフ・サーバー(PGX)では、Kerberosがアイデンティティ・プロバイダとして有効になっているOracle Databaseを使用してユーザーを認証できます。

Kerberosチケットを使用してグラフ・サーバーにログインでき、グラフ・サーバーで実行できるアクションは、Oracle Databaseで付与されているロールによって決まります。

14.2.4.9.1 前提条件

グラフ・サーバー(PGX)でKerberos認証を有効にするには、次のシステム要件を満たす必要があります。

  • データベースでKerberos認証が有効になっている必要があります。詳細は、Kerberos認証の構成を参照してください。
  • グラフ・サーバーが実行されるホストからデータベースとKerberos認証サーバーの両方に到達可能である必要があります。
  • データベースがグラフ・サーバー認証用に準備されています。つまり、関連するグラフ・ロールが、グラフ・サーバーにログインするユーザーに付与されています。

14.2.4.9.2 Kerberos認証のためのグラフ・サーバーの準備

グラフ・サーバー(PGX)でKerberos認証を有効にするステップは、次のとおりです。
  1. インストールのpgx.confファイルを見つけます。

    ノート:

    RPMを使用してグラフ・サーバーをインストールした場合、ファイルは/etc/oracle/graph/pgx.confにあります。
  2. pgx.confファイル内で、レルム・オプションのkrb5_conf_file行を探します。
    "pgx_realm": {
      "implementation": "oracle.pg.identity.DatabaseRealm",
      "options": {
        ...
        "krb5_conf_file": "<REPLACE-WITH-KRB5-CONF-FILE-PATH-TO-ENABLE-KERBEROS-AUTHENTICATION>",
        "krb5_ticket_cache_dir": "/dev/shm",
        "krb5_max_cache_size": 1024
      }
    },
  3. そのテキストを、データベースおよびユーザー認証に使用するkrb5.confファイルに置き換えます。たとえば:
    "pgx_realm": {
      "implementation": "oracle.pg.identity.DatabaseRealm",
      "options": {
        ...
        "krb5_conf_file": "/etc/krb5.conf",
        "krb5_ticket_cache_dir": "/dev/shm",
        "krb5_max_cache_size": 1024
      }
    },

    ノート:

    krb5_conf_fileオプションに指定するファイルは、有効であり、かつグラフ・サーバーによって読取り可能である必要があります。krb5_conf_file値を置き換えない場合、または値が空の場合、グラフ・サーバーではKerberos認証が使用されません。

    また、クライアントによって提供されたKerberosチケットを一時的に格納するためにグラフ・サーバーで使用されるキャッシュ・ディレクトリ、および新しいログイン試行が拒否されるようになる最大キャッシュ・サイズを設定できます。キャッシュ・サイズは、グラフ・サーバー上でアクティブな同時Kerberosセッションの最大数を表します。

14.2.4.9.3 Kerberosチケットを使用したグラフ・サーバーへのログイン

Kerberosチケットを使用してグラフ・サーバー(PGX)にログインするステップは、次のとおりです。
  1. okinitコマンドを使用して、新しいKerberosチケットを作成します。
    $ okinit <username>

    これにより、パスワードの入力を求められ、新しいKerberosチケットが作成されます。

  2. JShellを使用して、ベースURLパラメータのみを指定してリモート・グラフ・サーバーに接続します。
    $ opg4j -b https://localhost:7007
    または、Pythonクライアントを使用します。
    $ opg4py -b https://localhost:7007
    Linuxでは、JShellおよびPython対話型クライアント・シェルによってローカル・ファイル・システム上のKerberosチケットが自動的に検出され、それを使用してグラフ・サーバーで認証されます。
  3. 自動検出が機能しない場合は、チケットをシェルに明示的に渡すこともできます。oklistコマンドを実行して、ローカル・ファイル・システム上のチケットの場所を探します。
    $ oklist
     
    Kerberos Utilities for Linux: Version 19.0.0.0.0 - Production on 31-MAR-2021 15:26:46
     
    Copyright (c) 1996, 2019 Oracle.  All rights reserved.
     
    Configuration file : /etc/krb5.conf.
    Ticket cache: FILE:/tmp/krb5cc_54321
    Default principal: oracle@realm
  4. --kerberos_ticketパラメータを使用して、Kerberosチケットのパスを指定します。たとえば、JShellを使用します。
    $ opg4j -b https://localhost:7007 --kerberos_ticket /tmp/krb5cc_54321
    または、Pythonクライアントを使用します。
    $ opg4py -b https://localhost:7007 --kerberos_ticket /tmp/krb5cc_54321

    Javaクライアント・プログラム(または埋込みモードでJShell)を使用している場合は、次のAPIを使用してサーバー・インスタンスを取得できます。

    ...
    ServerInstance instance = GraphServer.getInstance("https://localhost:7007", "/tmp/krb5cc_54321");
    PgxSession session = instance.createSession("my-session");
    ...

    Pythonクライアント・プログラム(または埋込みモードでopg4py)を使用している場合は、次のAPIを使用してサーバー・インスタンスを取得できます

    ...
    instance = graph_server.get_instance("https://localhost:7007", "/tmp/krb5cc_54321")
    session = instance.create_session("my-session")
    ...
    リモート・グラフ・サーバーに接続する場合は、Oracle Graph Clientがインストールされていることのみが必要です。たとえば:
    import sys
    import pypgx as pgx
     
    sys.path.append("/path/to/graph/client/oracle-graph-client-21.2.0/python/pypgx/pg/rdbms")
     
    import graph_server
      
    base_url = "https://localhost:7007"
    kerberos_ticket = "/tmp/krb5cc_54321"
      
    instance = graph_server.get_instance(base_url, kerberos_ticket)
    print(instance)