SSPI assíncrono

O cabeçalho SSPI assíncrono inclui funções que dão suporte a objetos de contexto assíncrono, permitindo que os chamadores estabeleçam contextos de segurança entre o servidor e os clientes remotos simultaneamente por meio de um ciclo de vida de chamada assíncrona de SSPI.

Tipos de gerenciamento de contexto assíncrono

Nome do Objeto Descrição
SspiAsyncNotifyCallback Retorno de chamada usado para notificar a conclusão de uma chamada assíncrona de SSPI.

Funções de gerenciamento de contexto assíncrono

Nome da API Descrição
SspiCreateAsyncContext Cria uma instância de SspiAsyncContext que é usada para acompanhar a chamada assíncrona.
SspiReinitAsyncContext Marca um contexto assíncrono para reutilização.
SspiSetAsyncNotifyCallback Registra um retorno de chamada que é notificado sobre a conclusão de chamadas assíncronas.
SspiAsyncContextRequiresNotify Determina se um determinado contexto assíncrono requer notificação sobre a conclusão da chamada.
SspiGetAsyncCallStatus Obtém o status atual de uma chamada assíncrona associada ao contexto fornecido.
SspiFreeAsyncContext Libera um contexto criado na chamada para a função SspiCreateAsyncContext.

Funções assíncronas de SSPI

As funções a seguir aceitam um contexto assíncrono, além de todos os mesmos parâmetros que seu equivalente síncrono.

Nome da API Descrição
SspiAcquireCredentialsHandleAsync Adquire de forma assíncrona um identificador para pré-existentes credenciais de uma entidade de segurança.
SspiAcceptSecurityContextAsync Permite que o componente do servidor de um aplicativo de transporte estabeleça de forma assíncrona um contexto de segurança entre o servidor e um cliente remoto.
SspiInitializeSecurityContextAsync Inicializa um contexto de segurança assíncrona.
SspiDeleteSecurityContextAsync Exclui as estruturas de dados locais associadas ao contexto de segurança especificado iniciado por uma chamada anterior para a função SspiInitializeSecurityContextAsync ou a função SspiAcceptSecurityContextAsync.
SspiFreeCredentialsHandleAsync Libera um identificador de credencial.

Exemplo de API

Um fluxo de chamada típico funciona da seguinte maneira:

  1. Criar contexto SspiAsyncContext para acompanhar a chamada usando SspiCreateAsyncContext
  2. Registrar um SspiAsyncNotifyCallback para o contexto
  3. Fazer a chamada assíncrona usando SspiAcceptSecurityContextAsync
  4. No retorno de chamada, recupere o resultado usando SspiGetAsyncCallStatus
  5. Exclua SspiAsyncContext usando SspiDeleteSecurityContextAsync. Se reutilizar o contexto com SspiReinitAsyncContext, volte para a etapa 2.

O exemplo a seguir demonstra uma invocação de SspiAcceptSecurityContextAsync. O exemplo aguarda a conclusão da chamada e recupera o resultado.

Em um handshake SSPI completo, SspiAcceptSecurityContextAsync e SspiInitializeSecurityContextAsync seriam chamados várias vezes até que SEC_E_OK seja retornado. SspiReinitAsyncContext foi fornecido para facilitar o uso e facilitar o desempenho nesse caso.

As declarações são usadas para realçar o que esperaríamos no caso de êxito.

#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
}

Consulte Também

Cabeçalho sspi.h

Funções de SSPI

Estruturas de SSPI