Behandeln der Authentifizierung

Einige Proxys und Server erfordern eine Authentifizierung, bevor Sie zugriff auf Ressourcen im Internet gewähren. Die WinINet-Funktionen unterstützen die Server- und Proxyauthentifizierung für HTTP-Sitzungen. Die Authentifizierung von FTP-Servern muss von der InternetConnect-Funktion verarbeitet werden. Derzeit wird die FTP-Gatewayauthentifizierung nicht unterstützt.

Informationen zur HTTP-Authentifizierung

Wenn die Authentifizierung erforderlich ist, empfängt die Clientanwendung einen status Code 401, wenn der Server eine Authentifizierung erfordert, oder 407, wenn der Proxy eine Authentifizierung erfordert. Mit dem status Code sendet der Proxy oder Server einen oder mehrere Authentifizierungsantwortheader: Proxy-Authenticate (für die Proxyauthentifizierung) oder WWW-Authenticate (für die Serverauthentifizierung).

Jeder Authentifizierungsantwortheader enthält ein verfügbares Authentifizierungsschema und einen Bereich. Wenn mehrere Authentifizierungsschemas unterstützt werden, gibt der Server mehrere Authentifizierungsantwortheader zurück. Der Bereichswert berücksichtigt die Groß-/Kleinschreibung und definiert einen Schutzbereich auf dem Proxy oder Server. Der Header "WWW-Authenticate: Basic Realm="example"" wäre beispielsweise ein Beispiel für einen Header, der zurückgegeben wird, wenn die Serverauthentifizierung erforderlich ist.

Die Clientanwendung, die die Anforderung gesendet hat, kann sich authentifizieren, indem sie ein Autorisierungsheaderfeld mit der Anforderung einschließt. Der Autorisierungsheader enthält das Authentifizierungsschema und die entsprechende Antwort, die für dieses Schema erforderlich ist. Beispielsweise wird der Header "Authorization: Basic <username:password>" der Anforderung hinzugefügt und erneut an den Server gesendet, wenn der Client den Authentifizierungsantwortheader "WWW-Authenticate: Basic Realm="example" erhalten hat.

Es gibt zwei allgemeine Arten von Authentifizierungsschemas:

  • Standardauthentifizierungsschema, bei dem Benutzername und Kennwort in Klartext an den Server gesendet werden.
  • Challenge-Antwort-Schemas, die ein Challenge-Antwort-Format ermöglichen.

Das Standardauthentifizierungsschema basiert auf dem Modell, dass sich ein Client mit einem Benutzernamen und Kennwort für jeden Bereich authentifizieren muss. Der Server verarbeitet die Anforderung, wenn sie mit einem Autorisierungsheader erneut ausgeführt wird, der einen gültigen Benutzernamen und ein gültiges Kennwort enthält.

Herausforderungsantwortschemas ermöglichen eine sicherere Authentifizierung. Wenn eine Anforderung eine Authentifizierung mithilfe eines Challenge-Antwort-Schemas erfordert, werden die entsprechenden status-Code und Authentifizieren-Header an den Client zurückgegeben. Der Client muss die Anforderung dann mit einer Verhandlung erneut senden. Der Server würde einen entsprechenden status Code mit einer Challenge zurückgeben, und der Client müsste die Anforderung dann mit der richtigen Antwort erneut senden, um den angeforderten Dienst abzurufen.

In der folgenden Tabelle sind Authentifizierungsschemas, der Authentifizierungstyp, die DLL, die sie unterstützt, und eine Beschreibung des Schemas aufgeführt.

Schema type DLL Beschreibung
Basic (Klartext) basic Wininet.dll Verwendet eine base64-codierte Zeichenfolge, die den Benutzernamen und das Kennwort enthält.
Digest Challenge-Response Digest.dll Ein Challenge-Antwort-Schema, das die Verwendung eines Noncewerts (eine vom Server angegebene Datenzeichenfolge) inFrage stellt. Eine gültige Antwort enthält eine Prüfsumme des Benutzernamens, des Kennworts, des angegebenen Noncewerts, der HTTP-Methode und des angeforderten Uniform Resource Identifier (URI). Die Unterstützung der Digestauthentifizierung wurde in Microsoft Internet Explorer 5 eingeführt.
NT LAN-Manager (NTLM) Challenge-Response Winsspi.dll Ein Challenge-Antwort-Schema, das die Herausforderung auf dem Benutzernamen basiert.
Microsoft Network (MSN) Challenge-Response Msnsspc.dll Das Authentifizierungsschema des Microsoft-Netzwerks.
Verteilte Kennwortauthentifizierung (DPA) Challenge-Response Msapsspc.dll Ähnlich wie die MSN-Authentifizierung und wird auch vom Microsoft-Netzwerk verwendet.
Remotepassphrase Authentication (RPA) Compuserve Rpawinet.dll, da.dll CompuServe-Authentifizierungsschema. Weitere Informationen finden Sie unter RPA-Mechanismusspezifikationen.

 

Für andere Als die Standardauthentifizierung müssen die Registrierungsschlüssel zusätzlich zur Installation der entsprechenden DLL eingerichtet werden.

Wenn die Authentifizierung erforderlich ist, sollte das INTERNET_FLAG_KEEP_CONNECTION-Flag beim Aufruf von HttpOpenRequest verwendet werden. Das INTERNET_FLAG_KEEP_CONNECTION-Flag ist für NTLM und andere Authentifizierungstypen erforderlich, um die Verbindung während des Authentifizierungsprozesses aufrechtzuerhalten. Wenn die Verbindung nicht aufrechterhalten wird, muss der Authentifizierungsprozess mit dem Proxy oder Server neu gestartet werden.

Die Funktionen InternetOpenUrl und HttpSendRequest werden auch dann erfolgreich abgeschlossen, wenn eine Authentifizierung erforderlich ist. Der Unterschied besteht darin, dass die in den Headerdateien zurückgegebenen Daten und InternetReadFile eine HTML-Seite erhalten, die den Benutzer über den status Code informiert.

Registrieren von Authentifizierungsschlüsseln

INTERNET_OPEN_TYPE_PRECONFIG die Registrierungswerte ProxyEnable, ProxyServer und ProxyOverride. Diese Werte befinden sich unter HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Interneteinstellungen.

Bei anderen Authentifizierungsschemas als Basic muss der Registrierung unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security ein Schlüssel hinzugefügt werden. Ein DWORD-Wert , Flags, sollte mit dem entsprechenden Wert festgelegt werden. Die folgende Liste zeigt die möglichen Werte für den Flags-Wert .

  • PLUGIN_AUTH_FLAGS_UNIQUE_CONTEXT_PER_TCPIP (value=0x01)

    Jeder TCP/IP-Socket (Transmission Control Protocol/Internet Protocol) enthält einen anderen Kontext. Andernfalls wird für jede Bereichs- oder Block-URL-Vorlage ein neuer Kontext übergeben.

  • PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI (value=0x02)

    Diese DLL kann ihre eigene Benutzereingabe verarbeiten.

  • PLUGIN_AUTH_FLAGS_CAN_HANDLE_NO_PASSWD (value=0x04)

    Diese DLL ist möglicherweise in der Lage, eine Authentifizierung durchzuführen, ohne den Benutzer zur Eingabe eines Kennworts aufzufordern.

  • PLUGIN_AUTH_FLAGS_NO_REALM (value=0x08)

    Diese DLL verwendet keine standardmäßige HTTP-Bereichszeichenfolge. Alle Daten, die ein Bereich zu sein scheinen, sind schemaspezifische Daten.

  • PLUGIN_AUTH_FLAGS_KEEP_ALIVE_NOT_REQUIRED (value=0x10)

    Für diese DLL ist keine dauerhafte Verbindung für die Challenge-Antwort-Sequenz erforderlich.

Um beispielsweise die NTLM-Authentifizierung hinzuzufügen, muss der SCHLÜSSEL NTLM HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security hinzugefügt werden. Unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security\NTLM müssen der Zeichenfolgenwert DLLFile und der DWORD-WertFlags hinzugefügt werden. DLLFile muss auf Winsspi.dll festgelegt werden, und Flags muss auf 0x08 festgelegt werden.

Serverauthentifizierung

Wenn ein Server eine Anforderung empfängt, die eine Authentifizierung erfordert, gibt der Server eine Codemeldung vom Typ 401 status zurück. In dieser Nachricht sollte der Server mindestens einen WWW-Authenticate Antwortheader enthalten. Diese Header enthalten die vom Server verfügbaren Authentifizierungsmethoden. WinINet wählt die erste Methode aus, die es erkennt.

Die Standardauthentifizierung bietet schwache Sicherheit, es sei denn, der Kanal wird zuerst mit SSL oder PCT verschlüsselt.

Die InternetErrorDlg-Funktion kann verwendet werden, um den Benutzernamen und die Kennwortdaten des Benutzers abzurufen, oder eine benutzerdefinierte Benutzeroberfläche kann zum Abrufen der Daten entworfen werden.

Eine benutzerdefinierte Schnittstelle kann die InternetSetOption-Funktion verwenden, um die INTERNET_OPTION_PASSWORD - und INTERNET_OPTION_USERNAME-Werte festzulegen und die Anforderung dann erneut an den Server zu senden.

Proxyauthentifizierung

Wenn ein Client versucht, einen Proxy zu verwenden, der eine Authentifizierung erfordert, gibt der Proxy eine 407 status Codenachricht an den Client zurück. In dieser Nachricht sollte der Proxy mindestens einen Proxy-Authenticate Antwortheader enthalten. Diese Header enthalten die vom Proxy verfügbaren Authentifizierungsmethoden. WinINet wählt die erste Methode aus, die es erkennt.

Die InternetErrorDlg-Funktion kann verwendet werden, um den Benutzernamen und die Kennwortdaten des Benutzers abzurufen, oder es kann eine benutzerdefinierte Benutzeroberfläche entworfen werden.

Eine benutzerdefinierte Schnittstelle kann die InternetSetOption-Funktion verwenden, um die werte INTERNET_OPTION_PROXY_PASSWORD und INTERNET_OPTION_PROXY_USERNAME festzulegen und die Anforderung dann erneut an den Proxy zu senden.

Wenn kein Proxybenutzername und -kennwort festgelegt sind, versucht WinINet, den Benutzernamen und das Kennwort für den Server zu verwenden. Dieses Verhalten ermöglicht es Clients, dieselbe benutzerdefinierte Benutzeroberfläche zu implementieren, die für die Verarbeitung der Serverauthentifizierung verwendet wird.

Behandeln der HTTP-Authentifizierung

Die HTTP-Authentifizierung kann entweder mit InternetErrorDlg oder einer benutzerdefinierten Funktion verarbeitet werden, die InternetSetOption verwendet oder eigene Authentifizierungsheader hinzufügt. InternetErrorDlg kann die Header untersuchen, die einem HINTERNET-Handle zugeordnet sind, um ausgeblendete Fehler zu finden, z. B. status Codes von einem Proxy oder Server. InternetSetOption kann verwendet werden, um den Benutzernamen und das Kennwort für den Proxy und den Server festzulegen. Für die MSN- und DPA-Authentifizierung muss InternetErrorDlg verwendet werden, um den Benutzernamen und das Kennwort festzulegen.

Für jede benutzerdefinierte Funktion, die eigene WWW-Authenticate oder Proxy-Authenticate-Header hinzufügt, sollte das flag INTERNET_FLAG_NO_AUTH festgelegt werden, um die Authentifizierung zu deaktivieren.

Das folgende Beispiel zeigt, wie InternetErrorDlg zur Verarbeitung der HTTP-Authentifizierung verwendet werden kann.

HINTERNET hOpenHandle,  hConnectHandle, hResourceHandle;
DWORD dwError, dwErrorCode;
HWND hwnd = GetConsoleWindow();

hOpenHandle = InternetOpen(TEXT("Example"),
                           INTERNET_OPEN_TYPE_PRECONFIG, 
                           NULL, NULL, 0);

hConnectHandle = InternetConnect(hOpenHandle,
                                 TEXT("www.server.com"), 
                                 INTERNET_INVALID_PORT_NUMBER,
                                 NULL,
                                 NULL, 
                                 INTERNET_SERVICE_HTTP,
                                 0,0);

hResourceHandle = HttpOpenRequest(hConnectHandle, TEXT("GET"),
                                  TEXT("/premium/default.htm"),
                                  NULL, NULL, NULL, 
                                  INTERNET_FLAG_KEEP_CONNECTION, 0);

resend:

HttpSendRequest(hResourceHandle, NULL, 0, NULL, 0);

// dwErrorCode stores the error code associated with the call to
// HttpSendRequest.  

dwErrorCode = hResourceHandle ? ERROR_SUCCESS : GetLastError();

dwError = InternetErrorDlg(hwnd, hResourceHandle, dwErrorCode, 
                           FLAGS_ERROR_UI_FILTER_FOR_ERRORS | 
                           FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
                           FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
                           NULL);

if (dwError == ERROR_INTERNET_FORCE_RETRY)
    goto resend;

// Insert code to read the data from the hResourceHandle
// at this point.

Im Beispiel wird dwErrorCode verwendet, um alle Fehler zu speichern, die dem Aufruf von HttpSendRequest zugeordnet sind. HttpSendRequest wird erfolgreich abgeschlossen, auch wenn der Proxy oder Server eine Authentifizierung erfordert. Wenn das FLAGS_ERROR_UI_FILTER_FOR_ERRORS-Flag an InternetErrorDlg übergeben wird, überprüft die Funktion die Header auf ausgeblendete Fehler. Diese ausgeblendeten Fehler enthalten alle Anforderungen für die Authentifizierung. InternetErrorDlg zeigt das entsprechende Dialogfeld an, um den Benutzer zur Eingabe der erforderlichen Daten aufzufordern. Die flags FLAGS_ERROR_UI_FLAGS_GENERATE_DATA und FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS sollten ebenfalls an InternetErrorDlg übergeben werden, damit die Funktion die entsprechende Datenstruktur für den Fehler erstellt und die Ergebnisse des Dialogfelds im HINTERNET-Handle speichert.

Der folgende Beispielcode zeigt, wie die Authentifizierung mit InternetSetOption behandelt werden kann.

HINTERNET hOpenHandle,  hResourceHandle, hConnectHandle;
DWORD dwStatus;
DWORD dwStatusSize = sizeof(dwStatus);
char strUsername[64], strPassword[64];

// Normally, hOpenHandle, hResourceHandle,
// and hConnectHandle need to be properly assigned.

hOpenHandle = InternetOpen(TEXT("Example"),
                           INTERNET_OPEN_TYPE_PRECONFIG,
                           NULL, NULL, 0);
hConnectHandle = InternetConnect(hOpenHandle,
                                 TEXT("www.server.com"),
                                 INTERNET_INVALID_PORT_NUMBER,
                                 NULL,
                                 NULL,
                                 INTERNET_SERVICE_HTTP,
                                 0,0);

hResourceHandle = HttpOpenRequest(hConnectHandle, TEXT("GET"),
                                  TEXT("/premium/default.htm"),
                                  NULL, NULL, NULL,
                                  INTERNET_FLAG_KEEP_CONNECTION,
                                  0);

resend:

HttpSendRequest(hResourceHandle, NULL, 0, NULL, 0);

HttpQueryInfo(hResourceHandle, HTTP_QUERY_FLAG_NUMBER |
              HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL);

switch (dwStatus)
{
    // cchUserLength is the length of strUsername and
    // cchPasswordLength is the length of strPassword.
    DWORD cchUserLength, cchPasswordLength;

    case HTTP_STATUS_PROXY_AUTH_REQ: // Proxy Authentication Required
        // Insert code to set strUsername and strPassword.

        // Insert code to safely determine cchUserLength and
        // cchPasswordLength. Insert appropriate error handling code.
        InternetSetOption(hResourceHandle,
                          INTERNET_OPTION_PROXY_USERNAME,
                          strUsername,
                          cchUserLength+1);

        InternetSetOption(hResourceHandle,
                          INTERNET_OPTION_PROXY_PASSWORD,
                          strPassword,
                          cchPasswordLength+1);
        goto resend;
        break;

    case HTTP_STATUS_DENIED:     // Server Authentication Required.
        // Insert code to set strUsername and strPassword.

        // Insert code to safely determine cchUserLength and
        // cchPasswordLength. Insert error handling code as
        // appropriate.
        InternetSetOption(hResourceHandle, INTERNET_OPTION_USERNAME,
                          strUsername, cchUserLength+1);
        InternetSetOption(hResourceHandle, INTERNET_OPTION_PASSWORD,
                          strPassword, cchPasswordLength+1);
        goto resend;
        break;
}

// Insert code to read the data from the hResourceHandle
// at this point.

Hinweis

WinINet unterstützt keine Serverimplementierungen. Darüber hinaus sollte es nicht von einem Dienst verwendet werden. Verwenden Sie für Serverimplementierungen oder Dienste Microsoft Windows HTTP Services (WinHTTP).