プライマリ・コンテンツに移動
Oracle® Database Real Application Security管理者および開発者ガイド
12cリリース1 (12.1)
B71274-08
目次へ移動
目次
索引へ移動
索引

前
次

B 列の認可のためのOCIおよびJDBCアプリケーションの構成

OCIを使用した列認可インジケータの取得について

Oracle Call Interface (OCI)アプリケーションは、データ・セキュリティ・ポリシーが有効になっているデータベース表にアクセスし、認可インジケータの列をテストできます。

  • 列がユーザーに対して認可されていないと判断された場合は、インジケータ「未認可」とともにnull列値がユーザーに戻されます。

  • 列認可を判断できない場合は、評価された列(または列式)値がインジケータ「不明」とともにユーザーに戻されます。列式評価に関係する基礎となる表の列のいずれかが未認可の場合、認可インジケータは「不明」となり、式評価の基礎となる列値としてnull値が使用されます。

  • 列がユーザーに対して認可済と判断された場合は、評価された列値およびインジケータが認可インジケータなしでユーザーに戻されます。

OCI戻りコードは、ユーザーに列認可情報を通知するためのものです。列の認可情報を取得するには、列バッファがバインドまたは定義されるときに戻りコード・バッファを提供する必要があります。列データがユーザー・バッファに戻された後で、認可情報の列に関連付けられている戻りコードをチェックできます。列認可インジケータは、アプリケーションによって定義されている変数またはバインド外変数の定義に適用できます。アプリケーションが列認可インジケータを取得していない場合は、戻りコード・バッファを提供する必要はありません。

戻りコードの取得の例

次の戻りコードを使用して、列認可を探します。

  • ORA-24530: 列値はユーザーに対して認可されていません

  • ORA-24531: 列値の認証が不明です。

  • ORA-24536: 列の認可が不明です

不明値の認可インジケータ(ORA-24531)がいずれかの列に対して戻された場合、OCIファンクション・ステータスはOCI_SUCCESS_WITHINFOになり、エラー処理でエラーORA-24536が警告として処理されます。警告を抑止するために、アプリケーションはフェッチの前に文の処理で属性OCI_ATTR_NO_COLUMN_AUTH_WARNINGTRUEに設定できます。

 no_warning = TRUE;
 OCIAttrSet(stmthp, OCI_HTYPE_STMT, (void *)&no_warning, 0,
            OCI_ATTR_NO_COLUMN_AUTH_WARNING, errhp);

OCI_ATTR_NO_COLUMN_AUTH_WARNINGのデフォルトのブール値はFALSEです。

例B-1に、戻りコードを取得するOCIコードを示します。

例B-1 列認可のためのOCIからの戻りコードの取得

OCIDefineByPos(stmthp, &dfnhp, errhp,  1, (void *)data_bufp,  (sb4)data_bufl,
               data_typ, (void *)&data_ind, (ub2 *)&data_rlen, 
               (ub2 *)&data_rcode, (ub4)OCI_DEFAULT);
status = OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
if (data_rcode == 24530)
    printf("column value not authorized, indicator=%d\n", data_ind);
else if (data_rcode == 24531)
         printf("column value authorization unknown, indicator=%d\n", data_ind);
else  {
       printf("column value authorized, indicator=%d\n", data_ind);
       /* process column data */
       ...
};

認可インジケータでの戻りコードおよびインジケータの使用方法について

列セキュリティのある表にアクセスするには、少なくとも列がバインドまたは定義されているときに戻りコードにアクセスする必要があります。戻りコードがアクセスされない場合、アプリケーションは、インジケータと値を正しく解釈できるように列値が他の手段で認可されているかどうかを認識する必要があります。

列のセキュリティが有効になっている場合にバインドまたは定義するインジケータも提供する必要があります。インジケータが提供されておらず、列値が認可されていないか不明な場合、OracleデータベースはエラーORA-1405を戻します。

列値の認可が不明な場合は、認可インジケータ(ORA-24531の場合)が、ユーザーに戻される通常の戻りコードに優先します。たとえば、列のnullフェッチ(ORA-1405)および列の切捨て(ORA-1406)は、null以外の列値が不明の認可インジケータとともに戻されるのと同時に発生することがあります。その場合、アプリケーションはこの列の戻りコードとしてORA-1405やORA-1406ではなくORA-24531を取得します。このため、アプリケーションは列の戻りコードORA-1405またはORA-1406に依存してnullフェッチまたは切り捨てられた正確な列を探すことはできません。

表B-1および表B-2に、認可インジケータの動作、戻りコード、インジケータおよび戻りステータスをまとめます。

不明の認可インジケータに関する警告について

不明の認可インジケータ(ORA-24531)がいずれかの列に対して戻される場合は、OCI警告がアプリケーションに戻されるため、OCIファンクション・ステータスはOCI_SUCCESSではなくOCI_SUCCESS_WITH_INFOになります。同時に、ORA-24536はアプリケーションに戻されるエラー・ハンドルに設定されます。この警告をチェックし、実行されるSQLを検証し、適切なアクションを実行する必要があります。エラーORA-24536は、列が認可されるか列のセキュリティが有効になっていない場合に戻されるエラーに優先します。

列値が未認可または認可済の場合、OCIファンクション・ステータス・コードは変更されません。

デフォルトでは、列認可警告は不明な認可に対してオンになります。アプリケーションはエラーを処理するように設計されている必要があります。アプリケーションで列セキュリティの準備ができており、不明な認可インジケータを無視する場合は、列値がフェッチされる前にOCI文ハンドルでOCI属性OCI_ATTR_NO_COLUMN_AUTH_WARNINGTRUEに設定することにより、OCI警告をオフにできます。

表B-1で、OCI戻りインジケータのデフォルトの認可動作を説明します。

表B-1 認可インジケータの動作(デフォルト)

列認可 列値 IND提供、RC提供 IND未提供、RC提供 IND提供、RC未提供 IND未提供、RC未提供

未認可

任意

OCI_SUCCESS

エラー = 0

IND = -1

RC = 24530

OCI_SUCCESS

エラー = 1405

IND = N/A

RC = 24530

OCI_SUCCESS

エラー = 0

IND = -1

RC = N/A

OCI_SUCCESS

エラー = 1405

IND =-N/A

RC = N/A

不明

Null

SUCCESS_WITH_INFO

エラー = 24536 (0)

IND = -1

RC = 24531 (0)

SUCCESS_WITH_INFO

エラー = 24536 (1405)

IND = N/A

RC = 24531 (1405)

SUCCESS_WITH_INFO

エラー = 24536 (0)

IND = -1

RC = N/A

SUCCESS_WITH_INFO

エラー = 24536 (1405)

IND = N/A

RC = N/A

不明

NULL以外かつ切捨てなし

SUCCESS_WITH_INFO

エラー = 24536 (0)

IND = 0

RC = 24531 (0)

SUCCESS_WITH_INFO

エラー = 24536 (0)

IND = N/A

RC = 24531 (0)

SUCCESS_WITH_INFO

エラー = 24536 (0)

IND = 0

RC = N/A

SUCCESS_WITH_INFO

エラー = 24536 (0)

IND = N/A

RC = N/A

不明

NULL以外かつ切捨てあり

SUCCESS_WITH_INFO

エラー = 24536 (24345)

IND = data_len

RC = 24531 (1406)

SUCCESS_WITH_INFO

エラー = 24536 (24345)

IND = N/A

RC = 24531 (1406)

SUCCESS_WITH_INFO

エラー = 24536 (1406)

IND = data_len

RC = N/A

SUCCESS_WITH_INFO

エラー = 24536 (1406)

IND = N/A

RC = N/A

関連項目:

Oracle Call Interfaceプログラマーズ・ガイドの表2-4に、列セキュリティなしのデフォルトのフェッチ動作が示されています

表B-2では、OCI_ATTR_NO_AUTH_WARNINGパラメータがTRUEに設定されている場合のデフォルトの動作を説明します。

表B-2 認可インジケータの動作(デフォルト) - OCI_ATTR_NO_AUTH_WARNING=TRUE

列認可 列値 IND提供、RC提供 IND未提供、RC提供 IND提供、RC未提供 IND未提供、RC未提供

不明

Null

エラー = 0

IND = -1

RC = 24531 (0)

エラー = 1405

IND = N/A

RC = 24531 (1405)

エラー = 0

IND = -1

RC = N/A)

エラー = 1405

IND = N/A

RC = N/A

不明

NULL以外かつ切捨てなし

エラー = 0

IND = 0

RC = 24531 (0)

エラー = 0

IND = N/A

RC = 24531 (0)

エラー = 0

IND = 0

RC = N/A

エラー = 0

IND = N/A

RC = N/A

不明

NULL以外かつ切捨てあり

SUCCESS_WITH_INFO

エラー = 24345

IND = data_len

RC = 24531 (1406)

SUCCESS_WITH_INFO

エラー = 24345

IND = N/A

RC = 24531 (1406)

エラー = 1406

IND = data_len

RC = N/A)

エラー = 1406

IND = N/A

RC = N/A

列セキュリティに関するOCIの記述の使用

OCIDescribeAny()ファンクションは、スキーマ・オブジェクトの明示的な記述を有効にします。アプリケーションでは、データをフェッチする前に列が列制約で保護されているかどうかを知ることが必要な場合があります。この情報を使用して、データおよびインジケータを処理するようアプリケーションをガイドできます。これは、動的SQLを処理するアプリケーションに特に役立ちます。OCIパラメータ・ハンドルの属性OCI_ATTR_XDS_POLICY_STATUSは、ub4データ型であり、次の値を持つことができます。

  • OCI_XDS_POLICY_NONE: 列またはポリシーのXDSポリシーは有効になっていません

  • OCI_XDS_POLICY_ENABLED: 列のポリシーは有効になっています

  • OCI_XDS_POLICY_UNKNOWN: ポリシーは不明です

列ステータスがOCI_XDS_POLICY_NONEの場合、列値は常に「認可済」です。列ステータスがOCI_XDS_POLICY_ENABLEDの場合、列値は「認可済」または「未認可」です。列ステータスがOCI_XDS_POLICY_UNKNOWNの場合、列値認可は常に「不明」です。

例B-2に、OCIDescribeAny()ファンクションを使用してスキーマ・オブジェクトのセットに対して明示的な記述を実行する方法を示します。

関連項目:

『Oracle Call Interfaceプログラマーズ・ガイド』

例B-2 明示的な記述を有効にするためのOCIDescribeAnyファンクションの使用

void desc_explicit()
{
  const char *table = "col_sec_tab";
  ub4 pos;
  ub2 numcol;
  OCIParam *paramh;
  OCIParam *collst;
  OCIParam *col;
  ub4 colnamelen, colseclen;
  ub1 colname[20];
  ub1 *colnm;
  ub4 colsec;
  ub4 tablen = strlen((char *)table);
 
  checkerr(errhp, OCIDescribeAny(svchp, errhp, (dvoid *)table, tablen,
                                 OCI_OTYPE_NAME, 0, OCI_PTYPE_TABLE, deschp));
 
  checkerr(errhp, OCIAttrGet(deschp, OCI_HTYPE_DESCRIBE, &paramh, 0,
                             OCI_ATTR_PARAM, errhp));
 
  checkerr(errhp, OCIAttrGet(paramh, OCI_DTYPE_PARAM, &numcol, 0,
                             OCI_ATTR_NUM_COLS, errhp));
 
 
  checkerr(errhp, OCIAttrGet(paramh, OCI_DTYPE_PARAM, &collst, 0,
                             OCI_ATTR_LIST_COLUMNS, errhp));
 
  printf("Number of columns = %d\n\n", numcol);
 
  printf(" Column No   Column Name   Column Security\n");
  printf(" ---------   -----------   ---------------\n\n");
 
 
  for (pos = 1; (ub4) pos <= numcol; pos++)
  {
    checkerr(errhp, OCIParamGet (collst, OCI_DTYPE_PARAM, errhp,
                                 (dvoid **)&col, pos));
 
    checkerr(errhp, OCIAttrGet ((dvoid *)col, (ub4) OCI_DTYPE_PARAM,
                                (dvoid **)&colnm, (ub4 *) &colnamelen,
                                (ub4) OCI_ATTR_NAME, errhp));
 
    memset (colname, ' ', 20);
    strncpy((char *)colname, (char *)colnm, colnamelen);
    colname[10] = '\0';
 
    checkerr(errhp, OCIAttrGet ((dvoid *)col, (ub4) OCI_DTYPE_PARAM,
                                (dvoid **)&colsec, (ub4 *) &colseclen,
                                (ub4) OCI_ATTR_XDS_POLICY_STATUS, errhp));
 
    printf("    %d         %s     %s\n", pos, colname,
                           ((colsec == OCI_XDS_POLICY_ENABLED) ? "ENABLED" :
                           ((colsec == OCI_XDS_POLICY_NONE)   ?  "NONE"    :
                           ((colsec == OCI_XDS_POLICY_UNKNOWN) ? "UNKNOWN" :
                                                                 "ERROR"))));
  }
 
  return;
}

JDBCを使用した列認可インジケータの取得について

JDBCアプリケーションは、データ・セキュリティ・ポリシーが有効になっているデータベース表にアクセスし、認可インジケータの列をテストできます。この項で説明するJDBC APIを使用して、表の列のセキュリティ属性およびユーザー認可を確認できます。

表の列のセキュリティ属性の確認について

oracle.jdbc.OracleResultSetMetaDataインタフェースのgetSecurityAttributeメソッドにより、列のデータ・セキュリティ・ポリシー属性を確認できます。セキュリティ属性の定義は次のとおりです。

public static enum SecurityAttribute
  { 
    NONE,
    ENABLED,
    UNKNOWN;
  }

SecurityAttributeに可能な値は、次のとおりです。

  • NONEは、列に対して列データ・セキュリティ・ポリシーが有効でないことを暗に意味します。これは、列にポリシーが適用されていないか、ポリシーが有効になっていないことを意味します。

  • ENABLEDは、列に対して列データ・セキュリティ・ポリシーが有効であることを暗に意味します。

  • UNKNOWNは、列の列データ・セキュリティ・ポリシーが不明であることを暗に意味します。この状況は、たとえば列が2つの列の和集合で、一方の列にのみデータ・セキュリティ属性がある場合に発生することがあります。

getSecurityAttributeメソッドには次のシグネチャがあります。

public SecurityAttribute getSecurityAttribute(int indexOfColumnInResultSet) throws SQLException;

getSecurityAttributeメソッドは、列のSecurityAttribute値を戻します。

関連項目:

getSecurityAttributeメソッドの使用例は、例B-3を参照してください

表の列のユーザー認可の確認について

oracle.jdbc.OracleResultSetインタフェースのgetAuthorizationIndicatorメソッドでは、列のAuthorizationIndicator属性を確認できます。AuthorizationIndicator属性の定義は次のとおりです。

public static enum AuthorizationIndicator
  { 
    NONE,
    UNAUTHORIZED,
    UNKNOWN;
  }

AuthorizationIndicatorに可能な値は、次のとおりです。

  • NONEは、列データへのアクセスが認可されていることを暗に意味します。ユーザーが明示的な認可を持つか、列にセキュリティ属性がない可能性があります。

  • UNAUTHORIZEDは、列データへのアクセスが認可されていないことを暗に意味します。

    列値が取得される場合、認可インジケータは列に対して有効な列制約ポリシーに基づいて評価されます。ユーザーが列値へのアクセスを認可されていない場合は、NULL値が認可インジケータAuthorizationIndicator.UNAUTHORIZEDとともにアプリケーションに戻されます。

    未認可のベース列に関連する列式がある場合は、評価された値がAuthorizationIndicator.UNAUTHORIZEDインジケータとともにアプリケーションに戻されます。アプリケーションは、戻されたデータを解釈する前に認可インジケータを検証する必要があります。

  • UNKNOWNは、認可インジケータを判断できないことを暗に意味します。

    サーバーは、機能の制限またはパフォーマンスの制約により、SELECTアイテムの認可インジケータの判断に失敗することがあります。この状況は、たとえば問合せに列式が関係し、上位演算子が認可済と想定されるかどうかをサーバーが計算できない場合に発生することがあります。このようなシナリオでは、サーバーは認可インジケータAuthorizationIndicator.UNKNOWNをアプリケーションに戻します。戻り値は、列式が基礎となる列値に対してどのように機能するかに応じて、NULLまたはNULL以外になります。

    アプリケーションは、UNKNOWN認可インジケータを検出した場合に、戻り値にアクセスする必要があるかどうかを判断する必要があります。問合せおよびその列式が基礎となる列からの未認可のNULL値を処理するように設計されている場合、アプリケーションは戻り値を使用できます。それ以外の場合、アプリケーションは戻り値に対して適切なアクションを実行することが必要な場合があります。

getAuthorizationIndicatorメソッドの形式は次のとおりです。

/**
 * Accepts the column index number as an argument and retrieves the corresponding column security AuthorizationIndicator value
 */
public AuthorizationIndicator getAuthorizationIndicator(int columnIndex) throws SQLException;

/**
 * Accepts the column name as a string and retrieves the column security AuthorizationIndicator value
 */
public AuthorizationIndicator getAuthorizationIndicator(String columnName)throws SQLException;

注意:

  • 引数で指定された索引が無効な場合、前のメソッドはSQLExceptionをスローします。

  • 列がマスクされている場合、JDBCユーザーにはNULL値として表示されます。この場合、例外はスローされません。

関連項目:

getAuthorizationIndicatorメソッドの使用例は、例B-3を参照してください

セキュリティ属性およびユーザー認可の確認の例

例B-3に、セキュリティ属性およびユーザー認可を確認するためのgetSecurityAttributeおよびgetAuthorizationメソッドの使用方法を示します。プログラムでは、サンプルEMP表を使用して手順を示します。

EMP表は次のように構成されています。

列番号 列タイトル セキュリティ属性

1

EMPNO

セキュリティ属性なし

2

ENAME

アクティブなセキュリティ

3

JOB

セキュリティ属性なし

4

MGR

アクティブなセキュリティ

5

HIREDATE

不明なセキュリティ属性

6

SAL

アクティブなセキュリティ

7

COMM

セキュリティ属性なし

6

DEPTNO

アクティブなセキュリティ

プログラムでは、次の処理が実行されます。

  1. EMP表から行を選択します
  2. getSecurityAttributeメソッドを使用して、結果セットの各列のセキュリティ設定を抽出します。これらを列見出しとして出力します
  3. getAuthorizationIndicatorメソッドを使用して、戻された列値のユーザー認可を確認します。プログラムは、これらの値を出力し、次のように書式設定します。

    NULLとして戻される未認可の値は4つのアスタリスク文字(****)で表現されます。

例B-3セキュリティ属性およびユーザー認可の確認

PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM EMP");
  ResultSet rs = pstmt.executeQuery();
  OracleResultSetMetaData metaData = 
   (OracleResultSetMetaData)rs.getMetaData();
  int nbOfColumns = metaData.getColumnCount();
  OracleResultSetMetaData.SecurityAttribute[] columnSecurity
    = new OracleResultSetMetaData.SecurityAttribute[nbOfColumns];
  // display which columns are protected:
  for(int i=0;i<nbOfColumns;i++)
  {
    columnSecurity[i] = metaData.getSecurityAttribute(i+1);
    System.out.print(columnSecurity[i]);
    System.out.print("\t");
  }
  System.out.println();
  System.out.println("---------------------------------------------");
  while(rs.next())
  {
    for(int colIndex=0;colIndex<nbOfColumns;colIndex++)
    {
      OracleResultSet.AuthorizationIndicator visibility
        = ((OracleResultSet)rs).getAuthorizationIndicator(colIndex+1);
      if(visibility == OracleResultSet.AuthorizationIndicator.UNAUTHORIZED)
        System.out.print("****");
      else
        System.out.print(rs.getString(colIndex+1));
      System.out.print("\t");
    }
    System.out.println("");
  }
  rs.close();
  pstmt.close();    

プログラムは次の出力を生成します。

NONE   ENABLED   NONE       ENABLED   UNKNOWN      ENABLED   NONE   ENABLED
----------------------------------------------------------------------------------
7369   SMITH     CLERK      7902      1980-12-17   ****      null   20  
7499   ALLEN     SALESMAN   7698      1981-02-20   ****      300    30  
7521   WARD      SALESMAN   7698      1981-02-22   ****      500    30
7566   JONES     MANAGER    7839      1981-04-02   ****      null   20  
7654   MARTIN    SALESMAN   7698      1981-09-28   ****      1400   30  
7698   BLAKE     MANAGER    7839      1981-05-01   ****      null   30  
7782   CLARK     MANAGER    7839      1981-06-09   ****      null   10  
7788   SCOTT     ANALYST    7566      1987-04-19   ****      null   20  
7839   KING      PRESIDENT  null      1981-11-17   ****      null   10  
7844   TURNER    SALESMAN   7698      1981-09-08   ****      0      30  
7876   ADAMS     CLERK      7788      1987-05-23   ****      null   20  
7900   JAMES     CLERK      7698      1981-12-03   ****      null   30  
7902   FORD      ANALYST    7566      1981-12-03   ****      null   20  
7934   MILLER    CLERK      7782      1982-01-23   ****      null   10