Asynchrone SSPI

Der asynchrone SSPI-Header enthält Funktionen, die asynchrone Kontextobjekte unterstützen, sodass Aufrufer über einen asynchronen SSPI-Aufruflebenszyklus gleichzeitig Sicherheitskontexte zwischen Server- und Remoteclients einrichten können.

Asynchrone Kontextverwaltungstypen

Objektname BESCHREIBUNG
SspiAsyncNotifyCallback Rückruf, der zum Benachrichtigen des Abschlusses eines asynchronen SSPI-Aufrufs verwendet wird.

Asynchrone Kontextverwaltungsfunktionen

API-Name BESCHREIBUNG
SspiCreateAsyncContext Erstellt eine Instanz von SspiAsyncContext, die zum Nachverfolgen des asynchronen Aufrufs verwendet wird.
SspiReinitAsyncContext Markiert einen asynchronen Kontext für die Wiederverwendung.
SspiSetAsyncNotifyCallback Registriert einen Rückruf, der bei abschluss des asynchronen Aufrufs benachrichtigt wird.
SspiAsyncContextRequiresNotify Bestimmt, ob für einen bestimmten asynchronen Kontext eine Benachrichtigung beim Abschluss des Aufrufs erforderlich ist.
SspiGetAsyncCallStatus Ruft den aktuellen Status eines asynchronen Aufrufs ab, der dem bereitgestellten Kontext zugeordnet ist.
SspiFreeAsyncContext Gibt einen Kontext frei, der im Aufruf der SspiCreateAsyncContext-Funktion erstellt wurde.

Asynchrone SSPI-Funktionen

Die folgenden Funktionen akzeptieren einen asynchronen Kontext zusätzlich zu den gleichen Parametern wie ihre synchrone Entsprechung.

API-Name BESCHREIBUNG
SspiAcquireCredentialsHandleAsync Übernimmt asynchron ein Handle für bereits vorhandene Anmeldeinformationen eines Sicherheitsprinzipals.
SspiAcceptSecurityContextAsync Ermöglicht der Serverkomponente einer Transportanwendung das asynchrone Einrichten eines Sicherheitskontexts zwischen dem Server und einem Remoteclient.
SspiInitializeSecurityContextAsync Initialisiert einen asynchronen Sicherheitskontext.
SspiDeleteSecurityContextAsync Löscht die lokalen Datenstrukturen, die dem angegebenen Sicherheitskontext zugeordnet sind, der durch einen vorherigen Aufruf der SspiInitializeSecurityContextAsync-Funktion oder der SspiAcceptSecurityContextAsync-Funktion initiiert wurde.
SspiFreeCredentialsHandleAsync Gibt ein Anmeldeinformationshand handle frei.

API-Beispiel

Ein typischer Aufruffluss funktioniert wie folgt:

  1. Erstellen eines SspiAsyncContext-Kontexts zum Nachverfolgen eines Aufrufs mithilfe von SspiCreateAsyncContext
  2. Registrieren eines SspiAsyncNotifyCallback für den Kontext
  3. Führen Sie den asynchronen Aufruf mithilfe von SspiAcceptSecurityContextAsync aus.
  4. Rufen Sie beim Rückruf das Ergebnis mithilfe von SspiGetAsyncCallStatus ab.
  5. Löschen Sie SspiAsyncContext mithilfe von SspiDeleteSecurityContextAsync. Wenn Sie den Kontext mit SspiReinitAsyncContext wiederverwenden,fahren Sie mit Schritt 2 fort.

Das folgende Beispiel veranschaulicht einen Aufruf von SspiAcceptSecurityContextAsync. Das Beispiel wartet auf den Abschluss des Aufrufs und ruft das Ergebnis ab.

In einem vollständigen SSPI-Handshake werden SspiAcceptSecurityContextAsync und SspiInitializeSecurityContextAsync mehrmals aufgerufen, bis SEC_E_OK zurückgegeben wird. SspiReinitAsyncContext wurde bereitgestellt, um die Benutzerfreundlichkeit zu erleichtern und die Leistung in diesem Fall zu erleichtern.

Asserts werden verwendet, um hervorzuheben, was wir bei einem Erfolg erwarten würden.

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

Weitere Informationen

sspi.h-Header

SSPI-Funktionen

SSPI-Strukturen