Асинхронный SSPI
Заголовок асинхронного SSPI включает функции, поддерживающие асинхронные объекты контекста, позволяющие вызывающим объектам устанавливать контексты безопасности между сервером и удаленными клиентами одновременно через жизненный цикл асинхронного вызова SSPI.
Асинхронные типы управления контекстом
Имени объекта | Описание |
---|---|
SspiAsyncNotifyCallback | Обратный вызов, используемый для уведомления о завершении асинхронного вызова SSPI. |
Асинхронные функции управления контекстом
Имя API | Описание |
---|---|
SspiCreateAsyncContext | Создает экземпляр SspiAsyncContext, который используется для отслеживания асинхронного вызова. |
SspiReinitAsyncContext | Помечает асинхронный контекст для повторного использования. |
SspiSetAsyncNotifyCallback | Регистрирует обратный вызов, который уведомляется о завершении асинхронного вызова. |
SspiAsyncContextRequiresNotify | Определяет, требуется ли для заданного асинхронного контекста уведомление о завершении вызова. |
SspiGetAsyncCallStatus | Возвращает текущее состояние асинхронного вызова, связанного с предоставленным контекстом. |
SspiFreeAsyncContext | Освобождает контекст, созданный в вызове функции SspiCreateAsyncContext. |
Асинхронные функции SSPI
Следующие функции принимают асинхронный контекст в дополнение ко всем тем же параметрам, что и их синхронный аналог.
Имя API | Описание |
---|---|
SspiAcquireCredentialsHandleAsync | Асинхронно получает дескриптор для предварительно созданных учетных данных субъекта безопасности. |
SspiAcceptSecurityContextAsync | Позволяет компоненту сервера транспортного приложения асинхронно устанавливать контекст безопасности между сервером и удаленным клиентом. |
SspiInitializeSecurityContextAsync | Инициализирует асинхронный контекст безопасности. |
SspiDeleteSecurityContextAsync | Удаляет локальные структуры данных, связанные с указанным контекстом безопасности, инициированным предыдущим вызовом функции SspiInitializeSecurityContextAsync или функции SspiAcceptSecurityContextAsync. |
SspiFreeCredentialsHandleAsync | Освобождает дескриптор учетных данных. |
Пример API
Типичный поток вызовов работает следующим образом:
- Создание контекста SspiAsyncContext для отслеживания вызова с помощью SspiCreateAsyncContext
- Регистрация SspiAsyncNotifyCallback для контекста
- Создание асинхронного вызова с помощью SspiAcceptSecurityContextAsync
- При обратном вызове получите результат с помощью SspiGetAsyncCallStatus
- Удалите SspiAsyncContext с помощью SspiDeleteSecurityContextAsync. При повторном использовании контекста с помощью SspiReinitAsyncContext вернитесь к шагу 2.
В приведенном ниже примере показано вызов SspiAcceptSecurityContextAsync. Пример ожидает завершения вызова и извлекает результат.
В полном подтверждении SSPI SspiAcceptSecurityContextAsync и SspiInitializeSecurityContextAsync будет вызываться несколько раз, пока не будет возвращено SEC_E_OK. SspiReinitAsyncContext предоставляется для простоты использования и упрощения производительности в этом случае.
Утверждения используются для того, чтобы подчеркнуть, что мы ожидали бы в случае успеха.
#include <sspi.h>
void AsyncCallCompleted(
_In_ SspiAsyncContext* AsyncContext,
_In_opt_ PVOID pCallbackData
)
{
// Get result.
SECURITY_STATUS Status = SspiGetAsyncCallStatus(AsyncContext);
ASSERT(SEC_E_OK == Status);
// *Perform any needed callback actions, use pCallbackData if needed*
// Clean up async context when done.
SspiFreeAsyncContext(AsyncContext);
}
void DoASCCall(
_In_opt_ PCredHandle phCred,
_In_opt_ PCtxtHandle phContext,
_In_opt_ PSecBufferDesc pInput,
_In_opt_ PSecBufferDesc pOutput,
_Out_ unsigned long* pfContextAttr,
_Out_opt_ PTimeStamp ptsExpiry
)
{
// Create context for async call
SspiAsyncContext* AsyncContext = SspiCreateAsyncContext();
// Check for out of memory condition
ASSERT(AsyncContext);
// Register callback that continues execution upon completion.
PVOID pCallbackData = … ; // *Setup any state needed for callback.*
SECURITY_STATUS Status = SspiSetAsyncNotifyCallback(AsyncContext,
AsyncCallCompleted,
pCallbackData);
ASSERT(SEC_E_OK == Status);
// Queue asynchronous call.
Status = SspiAcceptSecurityContextAsync(AsyncContext,
phCred,
phContext,
pInput,
ASC_REQ_CONNECTION,
SECURITY_NATIVE_DREP,
phContext,
pOutput,
pfContextAttr,
ptsExpiry);
// All async functions return the status of queueing the async call,
// not the call’s result.
ASSERT(SEC_E_OK == Status);
// At this point, the call can be pending or complete.
// If complete, the result or error is returned.
// For this example, we assume if it finished, it finished with SEC_E_OK.
Status = SspiGetAsyncCallStatus(AsyncContext);
ASSERT(SEC_I_ASYNC_CALL_PENDING == Status ||
SEC_E_OK == Status);
// Execution will continue in the callback upon completion
}