共用方式為


使用 C++ 設定驗證

WMI 的主要任務之一是透過 IWbemLocator::ConnectServer 傳回 IWbemServices 的代理指標。 透過 IWbemServices Proxy,您可以存取 WMI 基礎結構的功能。 不過,IWbemServices Proxy 的指標具有用戶端應用程式進程的身分識別,而不是 IWbemServices 程式的身分識別。 因此,如果您嘗試使用指標存取 IWbemServices,您可以接收到拒絕存取的程式代碼,例如 E_ACCESSDENIED。 若要避免拒絕存取錯誤,您必須使用呼叫 CoSetProxyBlanket 介面來設定新指標的身分識別。

提供者可以在命名空間上設定安全性,因此除非您在該命名空間的連線中使用封包隱私權(PktPrivacy),否則不會傳回任何數據。 這可確保數據在透過網路時加密。 如果您嘗試設定較低的驗證層級,您將會收到拒絕存取的訊息。 如需詳細資訊,請參閱 設定 Namepace 安全性描述元

如需在腳本中設定驗證的詳細資訊,請參閱 使用 VBScript設定預設進程安全性層級。

在遠端 IUnknown 介面上設定安全性

在某些情況下,對伺服器的訪問權限需要超越僅僅是 Proxy 的指標。 有時候,您可能需要取得與 Proxy IUnknown 介面的安全連線。 使用 IUnknown,您可以查詢遠端系統是否有介面和其他必要技術。

當 Proxy 位於遠端電腦上時,伺服器會將 Proxy IUnknown 介面的所有呼叫委派給 IUnknown 介面。 例如,如果您在 Proxy 上呼叫 QueryInterface,且要求介面不是 Proxy 的一部分,Proxy 會將呼叫傳送至遠端伺服器。 接著,遠端伺服器會檢查適當的介面支援。 如果伺服器確實支援 介面,COM 會將新的 Proxy 封送處理回用戶端,讓應用程式可以使用新的介面。

如果客戶端沒有遠端伺服器的訪問許可權,但正在使用該伺服器之用戶的認證,就會發生問題。 在此情況下,任何嘗試在遠端伺服器上存取 QueryInterface 都失敗。 Proxy 的最終版本也會失敗,因為目前的用戶無法存取遠端伺服器。 其徵兆是用戶端應用程式在最終 Proxy 版本失敗前的一或兩秒延遲。 失敗的原因是 COM 嘗試使用目前使用者的預設安全設定來存取遠端伺服器,而這些設定並不包括最初允許存取伺服器的修改憑證。 如需詳細資訊,請參閱 在 IWbemServices 和其他 Proxy 上設定安全性

若要避免連線失敗,請使用 CoSetProxyBlanket,在從 IUnknown 傳回的指標上明確設定安全性驗證。 使用 CoSetProxyBlanket,您可以確定遠端伺服器會收到正確的驗證身分識別。

下列程式代碼範例示範如何使用 CoSetProxyBlanket 來存取遠端 IUnknown 介面。

SEC_WINNT_AUTH_IDENTITY_W* pAuthIdentity = 
   new SEC_WINNT_AUTH_IDENTITY_W;
ZeroMemory(pAuthIdentity, sizeof(SEC_WINNT_AUTH_IDENTITY_W));

pAuthIdentity->User = new WCHAR[32];
StringCbCopyW(pAuthIdentity->User,sizeof(L"MyUser"),L"MyUser");
pAuthIdentity->UserLength = wcslen(pAuthIdentity->User);

pAuthIdentity->Domain = new WCHAR[32];
StringCbCopyW(pAuthIdentity->Domain,sizeof(L"MyDomain"),L"MyDomain");
pAuthIdentity->DomainLength = wcslen(pAuthIdentity->Domain);

pAuthIdentity->Password = new WCHAR[32];
pAuthIdentity->Password[0] = NULL;
pAuthIdentity->PasswordLength = wcslen( pAuthIdentity->Password);

pAuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

IWbemServices* pWbemServices = 0;

// Set proxy security
hr = CoSetProxyBlanket(pWbemServices, 
                       RPC_C_AUTHN_DEFAULT, 
                       RPC_C_AUTHZ_NONE, 
                       COLE_DEFAULT_PRINCIPAL, 
                       RPC_C_AUTHN_LEVEL_DEFAULT, 
                       RPC_C_IMP_LEVEL_IMPERSONATE, 
                       pAuthIdentity, 
                       EOAC_NONE 
);
if (FAILED(hr))
{
   cout << "Count not set proxy blanket. Error code = 0x"
        << hex << hr << endl;
   pWbemServices->Release();
   return 1;
}

// Set IUnknown security
IUnknown*    pUnk = NULL;
pWbemServices->QueryInterface(IID_IUnknown, (void**) &pUnk);

hr = CoSetProxyBlanket(pUnk, 
                       RPC_C_AUTHN_DEFAULT, 
                       RPC_C_AUTHZ_NONE, 
                       COLE_DEFAULT_PRINCIPAL, 
                       RPC_C_AUTHN_LEVEL_DEFAULT, 
                       RPC_C_IMP_LEVEL_IMPERSONATE, 
                       pAuthIdentity, 
                       EOAC_NONE 
);
if (FAILED(hr))
{
   cout << "Count not set proxy blanket. Error code = 0x"
        << hex << hr << endl;
   pUnk->Release();
   pWbemServices->Release();
   delete [] pAuthIdentity->User;
   delete [] pAuthIdentity->Domain;
   delete [] pAuthIdentity->Password;
   delete pAuthIdentity;   
   return 1;
}

// cleanup IUnknown
pUnk->Release();

//
// Perform a bunch of operations
//

// Cleanup
pWbemServices->Release();

delete [] pAuthIdentity->User;
delete [] pAuthIdentity->Domain;
delete [] pAuthIdentity->Password;

delete pAuthIdentity;

注意

當您在 proxy 的 IUnknown 介面上設定安全性時,COM 會建立 Proxy 的複本,直到您呼叫 CoUninitialize之後,才能釋放該 Proxy。

 

在 WMI 中設定驗證