Freigeben über


Festlegen der Authentifizierung mit C++

Eine der Hauptaufgaben von IWbemLocator::ConnectServer für WMI besteht darin, einen Zeiger auf einen IWbemServices-Proxy zurückzugeben. Über den IWbemServices-Proxy können Sie auf die Funktionen der WMI-Infrastruktur zugreifen. Der Zeiger auf den IWbemServices-Proxy weist jedoch die Identität des Clientanwendungsprozesses und nicht die Identität des IWbemServices-Prozesses auf. Wenn Sie daher versuchen, mit dem Zeiger auf IWbemServices zuzugreifen, können Sie einen Zugriff verweigerten Code wie E_ACCESSDENIED erhalten. Um den Fehler "Zugriff verweigert" zu vermeiden, müssen Sie die Identität des neuen Zeigers mit einem Aufruf der CoSetProxyBlanket-Schnittstelle festlegen.

Ein Anbieter kann die Sicherheit für einen Namespace festlegen, sodass keine Daten zurückgegeben werden, es sei denn, Sie verwenden den Paketdatenschutz (PktPrivacy) in Ihrer Verbindung mit diesem Namespace. Dadurch wird sichergestellt, dass Daten verschlüsselt werden, während sie das Netzwerk durchquert. Wenn Sie versuchen, eine niedrigere Authentifizierungsstufe festzulegen, erhalten Sie eine Nachricht mit Zugriff verweigert. Weitere Informationen finden Sie unter Festlegen von Namespacesicherheitsdeskriptoren.

Weitere Informationen zum Festlegen der Authentifizierung in Skripts finden Sie unter Festlegen der Standardprozesssicherheitsstufe mit VBScript.

Festlegen der Sicherheit auf einer IUnknown-Remoteschnittstelle

In einigen Situationen ist mehr Zugriff auf einen Server erforderlich als nur ein Zeiger auf einen Proxy. Manchmal müssen Sie möglicherweise eine sichere Verbindung mit der IUnknown-Schnittstelle des Proxys herstellen. Mit IUnknown können Sie das Remotesystem nach Schnittstellen und anderen erforderlichen Techniken abfragen.

Wenn sich ein Proxy auf einem Remotecomputer befindet, delegiert der Server alle Aufrufe an die IUnknown-Schnittstelle des Proxys an die IUnknown-Schnittstelle . Wenn Sie beispielsweise QueryInterface für einen Proxy aufrufen und die angeforderte Schnittstelle nicht Teil des Proxys war, sendet der Proxy den Aufruf an den Remoteserver. Der Remoteserver sucht wiederum nach der entsprechenden Schnittstellenunterstützung. Wenn der Server die Schnittstelle unterstützt, marshallt COM einen neuen Proxy zurück an den Client, sodass die Anwendung die neue Schnittstelle verwenden kann.

Probleme treten auf, wenn der Client keine Zugriffsberechtigungen für den Remoteserver besitzt, jedoch die Anmeldeinformationen eines Benutzers verwendet, der dies tut. In diesem Fall schlägt jeder Versuch, auf QueryInterface auf dem Remoteserver zuzugreifen, fehl. Die endgültige Version des Proxys schlägt ebenfalls fehl, da der aktuelle Benutzer keinen Zugriff auf den Remoteserver hat. Ein Symptom hierfür ist eine Verzögerung von ein oder zwei Sekunden, bevor die Clientanwendung in der endgültigen Proxyfreigabe scheitert. Der Fehler tritt auf, weil COM versucht hat, mithilfe der Standardsicherheitseinstellungen des aktuellen Benutzers auf den Remoteserver zuzugreifen, der nicht die geänderten Anmeldeinformationen enthält, die den Zugriff auf den Server an erster Stelle erlaubt haben. Weitere Informationen finden Sie unter Festlegen der Sicherheit für IWbemServices und andere Proxys.

Um die fehlgeschlagene Verbindung zu vermeiden, verwenden Sie CoSetProxyBlanket , um die Sicherheitsauthentifizierung für den von IUnknown zurückgegebenen Zeiger explizit festzulegen. Mit CoSetProxyBlanket können Sie sicherstellen, dass der Remoteserver die richtige Authentifizierungsidentität empfängt.

Das folgende Codebeispiel zeigt, wie CoSetProxyBlanket für den Zugriff auf eine Remote-IUnknown-Schnittstelle verwendet wird.

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;

Hinweis

Wenn Sie die Sicherheit auf der IUnknown-Schnittstelle eines Proxys festlegen, erstellt COM eine Kopie des Proxys, die erst freigegeben werden kann, wenn Sie CoUninitialize aufrufen.

 

Festlegen der Authentifizierung in WMI