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 durchgeführt werden. Derzeit wird die FTP-Gatewayauthentifizierung nicht unterstützt.
Informationen zur HTTP-Authentifizierung
Wenn eine Authentifizierung erforderlich ist, erhält die Clientanwendung den Statuscode 401, wenn der Server eine Authentifizierung erfordert, oder 407, wenn der Proxy eine Authentifizierung erfordert. Mit dem Statuscode sendet der Proxy oder Server mindestens einen Antwortheader zur Authentifizierung– Proxyauthentifizierung (für 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. Beim Bereichswert wird die Groß-/Kleinschreibung beachtet, und es wird ein Schutzbereich auf dem Proxy oder Server definiert. Beispielsweise wäre der Header "WWW-Authenticate: Basic Realm="example" ein Beispiel für einen Header, der zurückgegeben wird, wenn eine Serverauthentifizierung erforderlich ist.
Die Clientanwendung, die die Anforderung gesendet hat, kann sich authentifizieren, indem sie ein Autorisierungsheaderfeld in die Anforderung einschließt. Der Autorisierungsheader würde das Authentifizierungsschema und die entsprechende Antwort enthalten, die für dieses Schema erforderlich ist. Beispielsweise würde 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 als Klartext an den Server gesendet werden.
- Abfrage-/Antwortschemas, die ein Abfrage-Antwort-Format ermöglichen.
Das Standardauthentifizierungsschema basiert auf dem Modell, das ein Client sich mit einem Benutzernamen und kennwort für jeden Bereich authentifizieren muss. Der Server wartet die Anforderung, wenn sie erneut mit einem Autorisierungsheader gesendet wird, der einen gültigen Benutzernamen und ein gültiges Kennwort enthält.
Abfrage-/Antwortschemas ermöglichen eine sicherere Authentifizierung. Wenn eine Anforderung eine Authentifizierung mithilfe eines Abfrage-/Antwortschemas erfordert, werden der entsprechende Statuscode und die Authenticate-Header an den Client zurückgegeben. Der Client muss die Anforderung dann mit einer Aushandlung erneut senden. Der Server würde einen geeigneten Statuscode mit einer Abfrage zurückgeben, und der Client müsste dann die Anforderung mit der richtigen Antwort erneut senden, um den angeforderten Dienst abzurufen.
In der folgenden Tabelle sind die 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 Abfrage-Antwort-Schema, das die Verwendung eines Nonce-Werts (einer vom Server angegebenen Datenzeichenfolge) in Frage stellt. Eine gültige Antwort enthält eine Prüfsumme des Benutzernamens, des Kennworts, des angegebenen Nonce-Werts, 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 Abfrage-Antwort-Schema, das die Abfrage auf dem Benutzernamen basiert. |
| Microsoft Network (MSN) | Challenge-Response | Msnsspc.dll | das Authentifizierungsschema von The Microsoft Network. |
| Verteilte Kennwortauthentifizierung (Distributed Password Authentication, DPA) | Challenge-Response | Msapsspc.dll | Ähnlich wie die MSN-Authentifizierung und wird auch vom Microsoft-Netzwerk verwendet. |
| Remotepassphrase-Authentifizierung (RPA) | Compuserve | Rpawinet.dll, da.dll | CompuServe-Authentifizierungsschema. Weitere Informationen finden Sie in den RPA-Mechanismusspezifikationen. |
Für andere Zwecke als die Standardauthentifizierung müssen die Registrierungsschlüssel zusätzlich zur Installation der entsprechenden DLL eingerichtet werden.
Wenn eine Authentifizierung erforderlich ist, sollte das INTERNET _ FLAG KEEP _ _ CONNECTION-Flag beim Aufruf von HttpOpenRequestverwendet werden. Das FLAG INTERNET _ FLAG KEEP CONNECTION ist für _ _ NTLM und andere Authentifizierungstypen erforderlich, um die Verbindung beim Abschließen des Authentifizierungsprozesses beizubehalten. Wenn die Verbindung nicht beibehalten 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 und InternetReadFile zurückgegebenen Daten eine HTML-Seite erhalten, die den Benutzer über den Statuscode informiert.
Registrieren von Authentifizierungsschlüsseln
INTERNET _ OPEN _ TYPE _ PRECONFIG untersucht die Registrierungswerte ProxyEnable, ProxyServer und ProxyOverride. Diese Werte befinden sich unter HKEY _ CURRENT _ USER \ Software \ Microsoft \ Windows \ CurrentVersion Internet \ Einstellungen.
Bei anderen Authentifizierungsschemas als Basic muss der Registrierung unter HKEY _ LOCAL _ MACHINE SOFTWARE Microsoft Internet Explorer Security ein Schlüssel hinzugefügt \ \ \ \ werden. Der 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 ein neuer Kontext für jede Bereichs- oder Block-URL-Vorlage übergeben.
PLUGIN _ AUTH _ FLAGS _ CAN HANDLE UI _ _ (value=0x02)
Diese DLL kann ihre eigenen Benutzereingaben verarbeiten.
_PLUG-IN-AUTHENTIFIZIERUNGSFLAGS _ _ KÖNNEN KEIN _ _ PASSWD VERARBEITEN _ (value=0x04)
Diese DLL kann eine Authentifizierung durchfü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.
_PLUG-IN-AUTHENTIFIZIERUNGSFLAGS _ KEEP ALIVE NOT REQUIRED _ _ _ _ (value=0x10)
Diese DLL erfordert keine permanente Verbindung für ihre Abfrage-/Antwortsequenz.
Um z. B. 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-Wert Flags hinzugefügt werden. DLLFile muss auf Winsspi.dll und Flags auf 0x08 festgelegt werden.
Serverauthentifizierung
Wenn ein Server eine Anforderung empfängt, die eine Authentifizierung erfordert, gibt der Server die Statuscodemeldung 401 zurück. In dieser Meldung sollte der Server mindestens einen WWW-Authenticate Antwortheader enthalten. Diese Header enthalten die Authentifizierungsmethoden, die der Server zur Verfügung hat. WinINet wählt die erste Methode aus, die es erkennt.
Die Standardauthentifizierung bietet schwache Sicherheit, es sei denn, der Kanal ist zuerst mit SSL oder PCT verknüpft.
Die InternetErrorDlg-Funktion kann verwendet werden, um die Benutzernamen- und Kennwortdaten vom Benutzer abzurufen, oder eine benutzerdefinierte Benutzeroberfläche kann zum Abrufen der Daten entworfen werden.
Eine benutzerdefinierte Schnittstelle kann die InternetSetOption-Funktion verwenden, um die Werte INTERNET OPTION _ _ PASSWORD und INTERNET OPTION _ _ USERNAME 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-Statuscodemeldung an den Client zurück. In dieser Nachricht sollte der Proxy mindestens einen Proxy-Authenticate Antwortheader enthalten. Diese Header enthalten die Authentifizierungsmethoden, die über den Proxy verfügbar sind. WinINet wählt die erste Methode aus, die es erkennt.
Die InternetErrorDlg-Funktion kann verwendet werden, um die Benutzernamen- und Kennwortdaten vom Benutzer abzurufen, oder eine benutzerdefinierte Benutzeroberfläche kann entworfen werden.
Eine benutzerdefinierte Schnittstelle kann die InternetSetOption-Funktion verwenden, um die Werte INTERNET OPTION PROXY _ _ _ PASSWORD und INTERNET OPTION PROXY _ _ _ USERNAME festzulegen und dann die Anforderung erneut an den Proxy zu senden.
Wenn kein Proxybenutzername und kein Kennwort festgelegt sind, versucht WinINet, den Benutzernamen und das Kennwort für den Server zu verwenden. Durch dieses Verhalten können Clients dieselbe benutzerdefinierte Benutzeroberfläche implementieren, die für die Serverauthentifizierung verwendet wird.
Verarbeiten 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 einem HINTERNET-Handle zugeordneten Header untersuchen, um ausgeblendete Fehler zu finden, z. B. Statuscodes 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 INTERNET _ FLAG NO _ _ AUTH-Flag so festgelegt werden, dass die Authentifizierung deaktiviert wird.
Das folgende Beispiel zeigt, wie InternetErrorDlg zur Behandlung 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 HttpSendRequestzugeordnet 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. Zu diesen ausgeblendeten Fehlern gehören 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 InternetSetOptionbehandelt 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 sie nicht von einem Dienst verwendet werden. Verwenden Sie für Serverimplementierungen oder -dienste Microsoft Windows HTTP-Dienste (WinHTTP).