SSPI assíncrono

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

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 SSPI assíncrona.

Funções de gerenciamento de contexto assíncronas

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 chamada assíncrona.
SspiAsyncContextRequiresNotify Determina se um determinado contexto assíncrono requer notificação após 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 SSPI assíncronas

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 credenciais pré-existentes de uma entidade de segurança.
SspiAcceptSecurityContextAsync Permite que o componente de 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 chamadas 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 estiver reutilizando 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 de 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 destacar o que esperaríamos no caso de sucesso.

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

Estruturas de SSPI