Асинхронный SSPI

Заголовок асинхронного SSPI включает функции, поддерживающие асинхронные объекты контекста, позволяющие вызывающим объектам устанавливать контексты безопасности между сервером и удаленными клиентами одновременно через жизненный цикл асинхронного вызова SSPI.

Асинхронные типы управления контекстом

Имени объекта Описание
SspiAsyncNotifyCallback Обратный вызов, используемый для уведомления о завершении асинхронного вызова SSPI.

Асинхронные функции управления контекстом

Имя API Описание
SspiCreateAsyncContext Создает экземпляр SspiAsyncContext, который используется для отслеживания асинхронного вызова.
SspiReinitAsyncContext Помечает асинхронный контекст для повторного использования.
SspiSetAsyncNotifyCallback Регистрирует обратный вызов, который уведомляется о завершении асинхронного вызова.
SspiAsyncContextRequiresNotify Определяет, требуется ли для заданного асинхронного контекста уведомление о завершении вызова.
SspiGetAsyncCallStatus Возвращает текущее состояние асинхронного вызова, связанного с предоставленным контекстом.
SspiFreeAsyncContext Освобождает контекст, созданный в вызове функции SspiCreateAsyncContext.

Асинхронные функции SSPI

Следующие функции принимают асинхронный контекст в дополнение ко всем тем же параметрам, что и их синхронный аналог.

Имя API Описание
SspiAcquireCredentialsHandleAsync Асинхронно получает дескриптор для предварительно созданных учетных данных субъекта безопасности.
SspiAcceptSecurityContextAsync Позволяет компоненту сервера транспортного приложения асинхронно устанавливать контекст безопасности между сервером и удаленным клиентом.
SspiInitializeSecurityContextAsync Инициализирует асинхронный контекст безопасности.
SspiDeleteSecurityContextAsync Удаляет локальные структуры данных, связанные с указанным контекстом безопасности, инициированным предыдущим вызовом функции SspiInitializeSecurityContextAsync или функции SspiAcceptSecurityContextAsync.
SspiFreeCredentialsHandleAsync Освобождает дескриптор учетных данных.

Пример API

Типичный поток вызовов работает следующим образом:

  1. Создание контекста SspiAsyncContext для отслеживания вызова с помощью SspiCreateAsyncContext
  2. Регистрация SspiAsyncNotifyCallback для контекста
  3. Создание асинхронного вызова с помощью SspiAcceptSecurityContextAsync
  4. При обратном вызове получите результат с помощью SspiGetAsyncCallStatus
  5. Удалите 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
}

См. также:

Заголовок sspi.h

Функции SSPI

Структуры SSPI