Настройка проверки подлинности с помощью C++
Одной из main задач IWbemLocator::ConnectServer для WMI является возврат указателя на прокси-сервер IWbemServices. Через прокси-сервер IWbemServices можно получить доступ к возможностям инфраструктуры WMI. Однако указатель на прокси-сервер IWbemServices имеет удостоверение процесса клиентского приложения, а не удостоверение процесса IWbemServices . Поэтому при попытке получить доступ к IWbemServices с помощью указателя можно получить код с отказом в доступе, например E_ACCESSDENIED. Чтобы избежать ошибки отказа в доступе, необходимо задать удостоверение нового указателя с помощью вызова интерфейса CoSetProxyBlanket .
Поставщик может задать безопасность пространства имен таким образом, чтобы данные не возвращались, если вы не используете конфиденциальность пакетов (PktPrivacy) в подключении к пространству имен. Это гарантирует, что данные шифруются по мере того, как они пересекают сеть. При попытке задать более низкий уровень проверки подлинности вы получите сообщение об отказе в доступе. Дополнительные сведения см. в разделе Настройка дескрипторов безопасности для платформы имен.
Дополнительные сведения о настройке проверки подлинности в скриптах см. в разделе Настройка уровня безопасности процесса по умолчанию с помощью VBScript.
Настройка безопасности в удаленном интерфейсе IUnknown
В некоторых ситуациях требуется больше доступа к серверу, чем просто указатель на прокси-сервер. Иногда может потребоваться безопасное подключение к интерфейсу IUnknown прокси-сервера. С помощью IUnknown можно запросить у удаленной системы интерфейсы и другие необходимые методы.
Если прокси-сервер находится на удаленном компьютере, сервер делегирует все вызовы интерфейса IUnknown прокси-сервера интерфейсу IUnknown . Например, если вы вызываете QueryInterface на прокси-сервере и запрошенный интерфейс не был частью прокси-сервера, прокси-сервер отправляет вызов удаленному серверу. В свою очередь, удаленный сервер проверяет наличие соответствующей поддержки интерфейса. Если сервер поддерживает интерфейс , COM маршалирует новый прокси-сервер обратно клиенту, чтобы приложение пользовалось новым интерфейсом.
Проблемы возникают, если клиент не имеет разрешений на доступ к удаленному серверу, но использует учетные данные пользователя, который это делает. В этом случае любая попытка получить доступ к QueryInterface на удаленном сервере завершается сбоем. Окончательный выпуск на прокси-сервере также завершается сбоем, так как текущий пользователь не имеет доступа к удаленному серверу. Признаком этого является задержка в одну или две секунды, прежде чем клиентское приложение не сможет окончательно освободить прокси-сервер. Сбой происходит из-за того, что COM попыталась получить доступ к удаленному серверу с помощью параметров безопасности по умолчанию текущего пользователя, которые не включают измененные учетные данные, разрешающие доступ к серверу. Дополнительные сведения см. в разделе Настройка безопасности для IWbemServices и других прокси-серверов.
Чтобы избежать неудачного подключения, используйте 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;
Примечание
При настройке безопасности в интерфейсе IUnknown прокси-сервера COM создает копию прокси-сервера, которая не может быть освобождена, пока вы не вызовете CoUninitialize.
Связанные темы