Impostazione dell'autenticazione con C++

Una delle attività principali di IWbemLocator::ConnectServer per WMI consiste nel restituire un puntatore a un proxy IWbemServices . Tramite il proxy IWbemServices è possibile accedere alle funzionalità dell'infrastruttura WMI. Tuttavia, il puntatore al proxy IWbemServices ha l'identità del processo dell'applicazione client e non l'identità del processo IWbemServices . Pertanto, se si tenta di accedere a IWbemServices con il puntatore, è possibile ricevere un codice di accesso negato, ad esempio E_ACCESSDENIED. Per evitare l'errore di accesso negato, è necessario impostare l'identità del nuovo puntatore con una chiamata all'interfaccia CoSetProxyBlanket .

Un provider può impostare la sicurezza in uno spazio dei nomi in modo che non vengano restituiti dati a meno che non si usi la privacy dei pacchetti (PktPrivacy) nella connessione a tale spazio dei nomi. In questo modo si garantisce che i dati vengano crittografati durante l'attraversamento della rete. Se si tenta di impostare un livello di autenticazione inferiore, verrà visualizzato un messaggio di accesso negato. Per altre informazioni, vedere Impostazione dei descrittori di sicurezza namepace.

Per altre informazioni sull'impostazione dell'autenticazione negli script, vedere Impostazione del livello di sicurezza del processo predefinito tramite VBScript.

Impostazione della sicurezza su un'interfaccia IUnknown remota

In alcune situazioni, è necessario un accesso maggiore a un server rispetto a un semplice puntatore a un proxy. A volte, potrebbe essere necessario ottenere una connessione sicura all'interfaccia IUnknown del proxy. Usando IUnknown, è possibile eseguire una query sul sistema remoto per individuare le interfacce e altre tecniche necessarie.

Quando un proxy si trova in un computer remoto, il server delega tutte le chiamate all'interfaccia IUnknown del proxy all'interfaccia IUnknown . Ad esempio, se si chiama QueryInterface su un proxy e l'interfaccia richiesta non faceva parte del proxy, il proxy invia la chiamata al server remoto. A sua volta, il server remoto verifica la presenza del supporto dell'interfaccia appropriato. Se il server supporta l'interfaccia, COM esegue il marshalling di un nuovo proxy al client in modo che l'applicazione possa usare la nuova interfaccia.

Si verificano problemi se il client non dispone delle autorizzazioni di accesso per il server remoto, ma usa le credenziali di un utente che lo esegue. In questo caso, qualsiasi tentativo di accesso a QueryInterface nel server remoto ha esito negativo. Anche la versione finale del proxy ha esito negativo, perché l'utente corrente non ha accesso al server remoto. Un sintomo di questo è un ritardo di uno o due secondi prima che l'applicazione client non riesca la versione finale del proxy. L'errore si verifica perché COM ha tentato di accedere al server remoto usando le impostazioni di sicurezza predefinite dell'utente corrente, che non includono le credenziali modificate che hanno consentito l'accesso al server al primo posto. Per altre informazioni, vedere Impostazione della sicurezza in IWbemServices e altri proxy.

Per evitare la connessione non riuscita, usare CoSetProxyBlanket per impostare in modo esplicito l'autenticazione di sicurezza sul puntatore restituito da IUnknown. Usando CoSetProxyBlanket, è possibile assicurarsi che il server remoto riceva l'identità di autenticazione corretta.

L'esempio di codice seguente illustra come usare CoSetProxyBlanket per accedere a un'interfaccia IUnknown remota.

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;

Nota

Quando si imposta la sicurezza sull'interfaccia IUnknown di un proxy, COM crea una copia del proxy che non può essere rilasciata finché non si chiama CoUninitialize.

 

Impostazione dell'autenticazione in WMI