共用方式為


使用 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 身分驗證層級預設) 預設安全性驗證。
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 伺服器可以模擬用戶端跨越多個界限,並可代表用戶端進行呼叫。