この章で説明する手順を実行してみる前に、「PersonQueryサンプル・アプリケーション」で解説した手順がすべて完了していることを確認してください。
InterceptorSecサンプル・インターセプタにより、基本的なセキュリティ・モデルを実装する単純なクライアント/サーバー・インターセプタのペアが示されます。InterceptorSecクライアント側インターセプタは単に、ORBで処理される各クライアント・リクエストをログに記録します。InterceptorSecターゲット・サイド・インターセプタは、クライアント・アプリケーションのユーザーがリクエストのオペレーションの実行を認可されているかどうかを確認する、単純なセキュリティ・メカニズムを実装します。
InterceptorSecサンプル・インターセプタでは、単一の初期化関数で初期化され、単一のライブラリに実装された、クライアントおよびターゲット・インターセプタのペアが示されます。単一の初期化関数が呼び出されるので、インターセプタ登録コマンドで登録されるのは初期化関数1つと実装ライブラリ1つです。
ターゲット・サイドORBでリクエストが受信されると、ORBはInterceptorSecターゲット・サイド・インターセプタを呼び出し、クライアント・リクエストからのRequestContext
およびDataInputStream
オブジェクトを渡します。
ターゲット・サイド・インターセプタはその後、次の処理により、クライアント・アプリケーションのユーザーに対してリクエストに含まれるオペレーションの認可を行います。
INVOKE_NO_EXCEPTION
を返します。PrimaryGroupId
およびAccessId
と照合します。ユーザーがこれら2つの属性の判定基準に問題なく一致していた場合、インターセプタはINVOKE_NO_EXCEPTION
を返します。REPLY_EXCEPTION
を返します。これにより、ターゲット・オブジェクトへのリクエストの送信は回避されます。その代わりに、ORBはクライアント・アプリケーションに例外を返します。以降の項ではインターセプタのセキュリティについて説明し、InterceptorSecターゲット・サイド・インターセプタの中から、該当するコードの抜粋部分を示します。
インターセプタは、Bootstrapオブジェクトではなく、ORBからSecurityCurrentオブジェクトを取得します。ORBから取得可能なSecurityCurrentオブジェクトには、インターセプタがクライアントの情報を取得するために必要とするAPIが含まれます。
インターセプタでORBに対するresolve_initial_references(“SecurityCurrent”)
オペレーションを呼び出すと、SecurityCurrentオブジェクトを取得できます。インターセプタは次に、SecurityCurrentリファレンスをSecurityCurrentLevel1
カレントにナロー変換します。
SecurityCurrentオブジェクトは、ORBからのみ取得可能です。このオブジェクトの主要な機能は、CORBAサーバー・アプリケーションがクライアント呼出し関連の属性にアクセスできるようにすることです。
ORBのresolve_initial_references("SecurityCurrent")
メソッドは、インターセプタにSecurityCurrentオブジェクトのリファレンスを提供します。このオブジェクトから、インターセプタにレベル1のセキュリティ機能が与えられます。インターセプタは、SecurityCurrentオブジェクトのget_attributes
メソッドを介してクライアント呼出しの属性を取得します。このオブジェクトは、属性リストをインターセプタに返します。属性リストには、インターセプトされている呼出しを実行したクライアント・アプリケーションのユーザーに関連する属性が含まれます。上記の例外を除けば、CORBAセキュリティ・サービスからのどのメソッドの振る舞いも同じです。
次のC++コードの抜粋では、SecurityCurrentオブジェクトの取得方法を示します。
try
{
sec_current = m_orb->resolve_initial_references("SecurityCurrent");
}
catch (...)
{
*m_outfile <<
"ERROR: ORB::resolve_initial_references threw exception"
<< endl << endl << flush;
excep_val = new CORBA::UNKNOWN();
return Interceptors::REPLY_EXCEPTION;
}
if (CORBA::is_nil(sec_current.in()))
{
*m_outfile << "ERROR: No SecurityCurrent present"
<< endl << endl << flush;
excep_val = new CORBA::NO_PERMISSION();
return Interceptors::REPLY_EXCEPTION;
}
m_security_current = SecurityLevel1::Current::_narrow(sec_current.in());
if (!m_security_current)
{
*m_outfile << "ERROR: Couldn't narrow security
current to SecurityLevel1::Current"
<< endl << endl << flush;
excep_val = new CORBA::NO_PERMISSION();
return Interceptors::REPLY_EXCEPTION;
}
この項のコード抜粋部分は、InterceptorSecターゲット・サイド・インターセプタが、ユーザー属性のリストを作成し、その後このリスト内を調べて、ユーザーが認可基準に適合しているかどうかを判定する方法を示します。
InterceptorSecサンプルでは、属性リストの作成と、そのリスト内容の検討は、個別の手順で行われます。長さ0のクライアント属性リストが返るように指定を行うと、SecurityCurrentオブジェクトはそのクライアントの全属性を返すことに注意してください。
// Get the attributes that correspond to the information that we need to
// do an authorization check:
// PrimaryGroupId (clientname of the logged in client)
// AccessId (username of the logged in client)
Security::AttributeList_var client_attr = 0;
try
{
client_attr = m_security_current->get_attributes(*m_attributes_to_get);
Security::AttributeTypeList_var attr = new Security::AttributeTypeList(2);
if (!attr.ptr())
{
cout <<
"ERROR: can't allocation security list: Out of memory"
<< endl << endl << flush;
return;
}
attr.inout().length(2);
attr[(CORBA::ULong)0].attribute_family.family_definer = 0;
attr[(CORBA::ULong)0].attribute_family.family = 1;
attr[(CORBA::ULong)0].attribute_type = Security::PrimaryGroupId;
attr[(CORBA::ULong)1].attribute_family.family_definer = 0;
attr[(CORBA::ULong)1].attribute_family.family = 1;
attr[(CORBA::ULong)1].attribute_type = Security::AccessId;
m_attributes_to_get = attr._retn();
return;
次の抜粋部分は、属性リストでユーザーが認可基準に適合するかどうかを確認する方法を示します。
if (client_attr[i].attribute_type.attribute_type == Security::PrimaryGroupId)
{
//
// This attribute is the client name.
// Compare to some client name value.
// For this example, we're going to accept anything with
// an 'r' in it, or a NULL string. You will want to compare
// the client name to some set of values you have authorized.
//
if ((strlen(value_buffer) == 0) ||
(strchr(value_buffer, 'r') != 0))
{
*m_outfile << " INFO: Valid client name found: "
<< value_buffer << endl;
clientname_ok = 1;
}
else
{
*m_outfile << " ERROR: Invalid client name found: "
<< value_buffer << endl;
}
}
else if (client_attr[i].attribute_type.attribute_type == Security::AccessId)
{
// This attribute is the user name. We're arbitrarily
// choosing to authorize anyone who has an 'r', 'n', or 'p'
// in their user id. You will likely want to choose
// some other criteria for authorization.
//
if ((strchr(value_buffer, 'r') != 0) ||
(strchr(value_buffer, 'R') != 0) ||
(strchr(value_buffer, 'P') != 0) ||
(strchr(value_buffer, 'p') != 0) ||
(strchr(value_buffer, 'N') != 0) ||
(strchr(value_buffer, 'n') != 0))
{
*m_outfile << " INFO: Valid username found: "
<< value_buffer << endl;
username_ok = 1;
}
「PersonQueryサンプル・アプリケーション」のPersonQueryサンプル・アプリケーションをビルドするmakefileを実行すると、InterceptorSecインターセプタを含むサンプル・インターセプタ一式全部が、同様にビルドされます。この項では、実行時にPersonQueryアプリケーションと共に機能するようにInterceptorSecインターセプタを登録する方法を説明します。
InterceptorSecクライアント・インターセプタおよびサーバー・インターセプタを登録して実行するには、以下の手順に従います。
workdirectory
は、「PersonQueryサンプル・アプリケーション」に示す手順でインターセプタのサンプル・アプリケーションをコピーしたディレクトリの名前を表します。> cd <workdirectory
>\cxx\security_cxx
$ cd <workdirectory
>/cxx/security_cxx
> nmake -f makefile.nt config
$ make -f makefile.mk config
> cd <workdirectory
>\cxx\app_cxx
> tmboot -y
> PersonQueryClient
> cd <workdirectory
>/cxx/app_cxx
> tmboot -y
> PersonQueryClient
> tmshutdown -y
InterceptorSecクライアント・インターセプタおよびターゲット・インターセプタは、指定されたファイルに出力のログを記録します。ファイル名はそれぞれ、InterceptorSecClientxxx.out
およびInterceptorSecTargetxxx.out
です。これらのファイルには、インターセプタからのデバッグ出力が含まれます。これはPersonQueryアプリケーション用に、ORBによって自動的にロードおよび実行されます。
InterceptorSecサンプル・インターセプタでPersonQueryサンプル・アプリケーションを実行後に、次の手順でこれらのインターセプタの登録を解除できます。
> tmshutdown -y
workdirectory
は、「PersonQueryサンプル・アプリケーション」に示す手順でインターセプタのサンプル・アプリケーションをコピーしたディレクトリの名前を表します。> cd <workdirectory
>\cxx\security_cxx
$ cd <workdirectory
>/cxx/security_cxx
> nmake -f makefile.nt unconfig
$ make -f makefile.mk unconfig