認証済み SSPI クライアントの作成
すべての RPC クライアント/サーバー セッションには、クライアントとサーバーの間のバインドが必要です。 クライアント/サーバー アプリケーションにセキュリティを追加するには、プログラムで認証済みバインディングを使用する必要があります。 このセクションでは、クライアントとサーバーの間で認証されたバインディングを作成するプロセスについて説明します。
関連情報については、プラットフォーム ソフトウェア開発キット (SDK) の 「ほとんどのセキュリティ パッケージとプロトコルで使用される手順 」を参照してください。
クライアント側バインド ハンドルの作成
サーバー プログラムとの認証済みセッションを作成するには、クライアント アプリケーションがバインド ハンドルを使用して認証情報を提供する必要があります。 認証されたバインド ハンドルを設定するために、クライアントは RpcBindingSetAuthInfo または RpcBindingSetAuthInfoEx 関数を 呼び出します。 これら 2 つの関数はほぼ同じです。 それらの唯一の違いは、クライアントが RpcBindingSetAuthInfoEx 関数を使用してサービスの品質を指定できることです。
次のコード フラグメントは、 RpcBindingSetAuthInfo の呼び出しがどのように見えるかを示しています。
// This code fragment assumes that rpcBinding is a valid binding
// handle between the client and the server. It also assumes that
// pAuthCredentials is a valid pointer to a data structure which
// contains the user's authentication credentials.
dwStatus = DsMakeSpn(
"ldap",
"ServerName.domain.com",
NULL,
0,
NULL,
&pcSpnLength,
pszSpn);
//...
rpcStatus = RpcBindingSetAuthInfo(
rpcBinding, // Valid binding handle
pszSpn, // Principal name
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, // Authentication level
RPC_C_AUTHN_GSS_NEGOTIATE, // Use Negotiate SSP
NULL, // Authentication credentials <entity type="ndash"/> use current thread credentials
RPC_C_AUTHZ_NAME); // Authorization service
クライアントが RpcBindingSetAuthInfo 関数または RpcBindingSetAuthInfoEx 関数を 正常に呼び出した後、RPC ランタイム ライブラリはバインドに対するすべての RPC 呼び出しを自動的に認証します。 クライアントが選択するセキュリティと認証のレベルは、そのバインド ハンドルにのみ適用されます。 バインド ハンドルから派生したコンテキスト ハンドルは同じセキュリティ情報を使用しますが、その後のバインディング ハンドルの変更はコンテキスト ハンドルに反映されません。 詳細については、「 コンテキスト ハンドル」を参照してください。
認証レベルは、クライアントが別のレベルを選択するか、プロセスが終了するまで有効です。 ほとんどのアプリケーションでは、セキュリティ レベルを変更する必要はありません。 クライアントは、 RpcBindingInqAuthClient を呼び出してバインド ハンドルを渡すことによって、任意のバインド ハンドルに対してクエリを実行して、その承認情報を取得できます。
サーバーへのクライアント資格情報の提供
サーバーは、クライアントのバインディング情報を使用してセキュリティを適用します。 クライアントは常に、リモート プロシージャ 呼び出しの最初のパラメーターとしてバインド ハンドルを渡します。 ただし、IDL ファイルまたはサーバーのアプリケーション構成ファイル (ACF) 内のリモート プロシージャの最初のパラメーターとして宣言されていない限り、サーバーはハンドルを使用できません。 IDL ファイルにバインド ハンドルを一覧表示することもできますが、これにより、すべてのクライアントは、自動または暗黙的なバインドを使用するのではなく、バインド ハンドルを宣言して操作するように強制されます。 詳細については、「 IDL ファイルと ACF ファイル」を参照してください。
もう 1 つの方法は、バインド ハンドルを IDL ファイルから除外し、 explicit_handle 属性をサーバーの ACF に配置することです。 このようにして、クライアントはアプリケーションに最も適したバインディングの種類を使用できますが、サーバーはバインディング ハンドルを明示的に宣言されたかのように使用します。
バインディング ハンドルからクライアント資格情報を抽出するプロセスは、次のようになります。
- RPC クライアントは RpcBindingSetAuthInfo を 呼び出し、サーバーに渡されるバインディング情報の一部として認証情報を含めます。
- 通常、サーバーは RpcImpersonateClient を 呼び出して、クライアントと同じように動作します。 バインド ハンドルが認証されていない場合、呼び出しはRPC_S_NO_CONTEXT_AVAILABLEで失敗します。 クライアントのユーザー名を取得するには、偽装中に RpcBindingInqAuthClient を呼び出すか、Windows XP 以降のバージョンの Windows で RpcGetAuthorizationContextForClient を呼び出して承認コンテキストを取得し、Authz 関数を使用して名前を取得します。
- 通常、サーバーは CreatePrivateObjectSecurity を呼び出して、ACL を使用してオブジェクトを作成します。 これが完了すると、後でセキュリティ チェックが自動的に行われます。