B 列の認可のためのOCIおよびJDBCアプリケーションの構成
OCIを使用した列認可インジケータの取得について
Oracle Call Interface (OCI)アプリケーションは、データ・セキュリティ・ポリシーが有効になっているデータベース表にアクセスし、認可インジケータの列をテストできます。
-
列がユーザーに対して認可されていないと判断された場合は、インジケータ「未認可」とともにnull列値がユーザーに戻されます。
-
列認可を判断できない場合は、評価された列(または列式)値がインジケータ「不明」とともにユーザーに戻されます。列式評価に関係する基礎となる表の列のいずれかが未認可の場合、認可インジケータは「不明」となり、式評価の基礎となる列値としてnull値が使用されます。
-
列がユーザーに対して認可済と判断された場合は、評価された列値およびインジケータが認可インジケータなしでユーザーに戻されます。
OCI戻りコードは、ユーザーに列認可情報を通知するためのものです。列の認可情報を取得するには、列バッファがバインドまたは定義されるときに戻りコード・バッファを提供する必要があります。列データがユーザー・バッファに戻された後で、認可情報の列に関連付けられている戻りコードをチェックできます。列認可インジケータは、アプリケーションによって定義されている変数またはバインド外変数の定義に適用できます。アプリケーションが列認可インジケータを取得していない場合は、戻りコード・バッファを提供する必要はありません。
戻りコードの取得の例
不明値の認可インジケータ(ORA-24531)がいずれかの列に対して戻された場合、OCIファンクション・ステータスはOCI_SUCCESS_WITHINFOになり、エラー処理でエラーORA-24536が警告として処理されます。警告を抑止するために、アプリケーションはフェッチの前に文の処理で属性OCI_ATTR_NO_COLUMN_AUTH_WARNINGをTRUEに設定できます。
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フェッチまたは切り捨てられた正確な列を探すことはできません。
不明の認可インジケータに関する警告について
不明の認可インジケータ(ORA-24531)がいずれかの列に対して戻される場合は、OCI警告がアプリケーションに戻されるため、OCIファンクション・ステータスはOCI_SUCCESSではなくOCI_SUCCESS_WITH_INFOになります。同時に、ORA-24536はアプリケーションに戻されるエラー・ハンドルに設定されます。この警告をチェックし、実行されるSQLを検証し、適切なアクションを実行する必要があります。エラーORA-24536は、列が認可されるか列のセキュリティが有効になっていない場合に戻されるエラーに優先します。
列値が未認可または認可済の場合、OCIファンクション・ステータス・コードは変更されません。
デフォルトでは、列認可警告は不明な認可に対してオンになります。アプリケーションはエラーを処理するように設計されている必要があります。アプリケーションで列セキュリティの準備ができており、不明な認可インジケータを無視する場合は、列値がフェッチされる前にOCI文ハンドルでOCI属性OCI_ATTR_NO_COLUMN_AUTH_WARNINGをTRUEに設定することにより、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の場合、列値は常に「認可済」です。列ステータスがOCI_XDS_POLICY_ENABLEDの場合、列値は「認可済」または「未認可」です。列ステータスがOCI_XDS_POLICY_UNKNOWNの場合、列値認可は常に「不明」です。
例B-2に、OCIDescribeAny()ファンクションを使用してスキーマ・オブジェクトのセットに対して明示的な記述を実行する方法を示します。
例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, ¶mh, 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は、列に対して列データ・セキュリティ・ポリシーが有効でないことを暗に意味します。これは、列にポリシーが適用されていないか、ポリシーが有効になっていないことを意味します。 -
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 |
|
セキュリティ属性なし |
|
2 |
|
アクティブなセキュリティ |
|
3 |
|
セキュリティ属性なし |
|
4 |
|
アクティブなセキュリティ |
|
5 |
|
不明なセキュリティ属性 |
|
6 |
|
アクティブなセキュリティ |
|
7 |
|
セキュリティ属性なし |
|
6 |
|
アクティブなセキュリティ |
プログラムでは、次の処理が実行されます。
例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