Share via


使用 C++ 設定預設進程安全性層級

當用戶端應用程式第一次登入 Windows Management Instrumentation (WMI) 時,它必須設定預設進程安全性層級,並呼叫 CoInitializeSecurity。 COM 會使用呼叫中的資訊來判斷另一個進程必須有多少安全性才能存取用戶端應用程式進程。

本主題將討論下列各節:

針對大部分用戶端應用程式,下列範例中顯示的引數會設定 WMI 的預設安全性。

HRESULT hr = NULL;
hr = CoInitializeSecurity(
        NULL,                       // security descriptor
       -1,                          // use this simple setting
       NULL,                        // use this simple setting
       NULL,                        // reserved
       RPC_C_AUTHN_LEVEL_DEFAULT,   // authentication level  
       RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
       NULL,                        // use this simple setting
       EOAC_NONE,                   // no special capabilities
       NULL);                          // reserved

if (FAILED(hr))
{
  CoUninitialize();
  cout << "Failed to initialize security. Error code = 0x"
       << hex << hr << endl;
  return;
}

程式碼需要下列參考和#include語句才能正確編譯。

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

將驗證層級設定為 RPC_C_AUTHN_LEVEL_DEFAULT 可讓 DCOM 交涉驗證層級,以符合目的電腦的安全性需求。 如需詳細資訊,請參閱 使用 C++ 變更預設驗證認證 和使用 C++ 變更預設模擬設定

使用 C++ 變更預設驗證認證

預設驗證認證適用于大部分情況,但您可能需要在不同的情況下使用不同的驗證認證。 例如,您可能想要將加密新增至驗證程式。

下表列出並描述不同層級的驗證。

驗證層級 描述
RPC_C_AUTHN_LEVEL_DEFAULT 預設安全性驗證。
RPC_C_AUTHN_LEVEL_NONE 不需要驗證。
RPC_C_AUTHN_LEVEL_CONNECT 只有在用戶端與伺服器建立關聯性時,才進行驗證。
RPC_C_AUTHN_LEVEL_CALL 每次伺服器收到 RPC 時驗證。
RPC_C_AUTHN_LEVEL_PKT 每次伺服器收到來自用戶端的資料時,都會進行驗證。
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 驗證封包中未修改任何資料。
RPC_C_AUTHN_LEVEL_PKT_PRIVACY 包含所有先前的驗證層級,並加密每個 RPC 呼叫的值。

 

您可以在CoInitializeSecuritypAuthList參數中使用SOLE_AUTHENTICATION_LIST結構,為多個使用者指定預設驗證認證。

下列程式碼範例示範如何變更驗證認證。

// Auth Identity structure
SEC_WINNT_AUTH_IDENTITY_W        authidentity;
SecureZeroMemory( &authidentity, sizeof(authidentity) );

authidentity.User = L"MyUser";
authidentity.UserLength = wcslen( authidentity.User );
authidentity.Domain = L"MyDomain ";
authidentity.DomainLength = wcslen( authidentity.Domain );
authidentity.Password = L"";
authidentity.PasswordLength = wcslen( authidentity.Password );
authidentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

SecureZeroMemory( authninfo, sizeof(SOLE_AUTHENTICATION_INFO)*2 );

// NTLM Settings
authninfo[0].dwAuthnSvc = RPC_C_AUTHN_WINNT;
authninfo[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
authninfo[0].pAuthInfo = &authidentity;

// Kerberos Settings
authninfo[1].dwAuthnSvc = RPC_C_AUTHN_GSS_KERBEROS ;
authninfo[1].dwAuthzSvc = RPC_C_AUTHZ_NONE;
authninfo[1].pAuthInfo = &authidentity;

SOLE_AUTHENTICATION_LIST    authentlist;

authentlist.cAuthInfo = 2;
authentlist.aAuthInfo = authninfo;

CoInitializeSecurity( 
  NULL, 
  -1, 
  NULL, 
  NULL, 
  RPC_C_AUTHN_LEVEL_CALL, 
  RPC_C_IMP_LEVEL_IMPERSONATE,
  &authentlist, 
  EOAC_NONE,
  NULL);

使用 C++ 變更預設模擬層級

COM 提供從系統登錄讀取的預設安全性層級。 不過,除非特別修改,否則登錄設定會將模擬層級設定為太低,WMI 才能運作。 一般而言,預設模擬層級 RPC_C_IMP_LEVEL_IDENTIFY,但 WMI 至少需要 RPC_C_IMP_LEVEL_IMPERSONATE 才能與大部分提供者搭配運作,而且您可能會遇到需要設定較高層級模擬的情況。 如需詳細資訊,請參閱 連線到遠端電腦上的 WMI。 下表列出不同的模擬層級。

層級 描述
RPC_C_IMP_LEVEL_DEFAULT 作業系統會選擇模擬的層級。
RPC_C_IMP_LEVEL_ANONYMOUS 伺服器可以模擬用戶端,但模擬權杖無法用於任何專案。
RPC_C_IMP_LEVEL_IDENTIFY 伺服器可以取得用戶端的身分識別,並模擬用戶端以進行 ACL 檢查。
RPC_C_IMP_LEVEL_IMPERSONATE 伺服器可以跨一部電腦界限模擬用戶端。
RPC_C_IMP_LEVEL_DELEGATE 伺服器可以模擬跨多個界限的用戶端,並可代表用戶端進行呼叫。