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:
- Erstellen eines SspiAsyncContext-Kontexts zum Nachverfolgen eines Aufrufs mithilfe von SspiCreateAsyncContext
- Registrieren eines SspiAsyncNotifyCallback für den Kontext
- Führen Sie den asynchronen Aufruf mithilfe von SspiAcceptSecurityContextAsync aus.
- Rufen Sie beim Rückruf das Ergebnis mithilfe von SspiGetAsyncCallStatus ab.
- 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
}