Řízení ověřování
Některé proxy servery a servery vyžadují ověření pro udělení přístupu k prostředkům na internetu. Funkce WinINet podporují ověřování serveru a proxy serveru pro relace HTTP. Ověřování ftp serverů musí zpracovat funkce InternetConnect. V současné době se ověřování brány FTP nepodporuje.
Informace o ověřování HTTP
Pokud se vyžaduje ověřování, klientská aplikace obdrží stavový kód 401, pokud server vyžaduje ověření, nebo 407, pokud proxy server vyžaduje ověření. Se stavovým kódem odešle proxy server nebo server jednu nebo více hlaviček odpovědi –Proxy-Authenticate (pro ověřování proxy serveru) nebo WWW-Authenticate (pro ověřování serveru).
Každá hlavička odpovědi pro ověření obsahuje dostupné schéma ověřování a doménu. Pokud se podporuje více schémat ověřování, server vrátí více hlaviček odpovědi pro ověření. Hodnota pole je rozlišována podle velikosti písmen a definuje ochranný prostor na proxy nebo serveru. Například hlavička "WWW-Authenticate: Basic Realm="example"" by byla příkladem hlavičky vrácené v případě, že je vyžadováno ověření serveru.
Klientská aplikace, která odeslala požadavek, se může ověřit zahrnutím pole hlavičky autorizace s požadavkem. Autorizační hlavička by obsahovala schéma ověřování a odpovídající odpověď vyžadovanou tímto schématem. Například hlavička "Authorization: Basic <username:password>" by byla přidána do požadavku a znovu odeslána na server, pokud klient obdržel hlavičku odpovědi pro ověření "WWW-Authenticate: Basic Realm="example".
Existují dva obecné typy schémat ověřování:
- Základní schéma ověřování, ve kterém se uživatelské jméno a heslo odesílají na server v jasném textu.
- Schémata výzva-odpověď, která umožňují použití formátu výzva-odpověď.
Schéma základního ověřování je založené na modelu, kde se klient musí ověřit pomocí uživatelského jména a hesla pro každou oblast. Server požadavek obsluhuje, pokud se znovu odešle s autorizační hlavičkou, která obsahuje platné uživatelské jméno a heslo.
Schémata odpovědí na výzvy umožňují bezpečnější ověřování. Pokud požadavek vyžaduje ověření pomocí systému Challenge-Response, vrátí se klientovi odpovídající stavový kód a hlavičky Authenticate. Klient pak musí žádost znovu odeslat za účelem jednání. Server vrátí odpovídající stavový kód s výzvou a klient pak bude muset žádost znovu odeslat se správnou odpovědí, aby získal požadovanou službu.
Následující tabulka uvádí schémata ověřování, typ ověřování, knihovnu DLL, která je podporuje, a popis schématu.
Pro cokoli jiného než základní ověřování musí být klíče registru nastaveny kromě instalace příslušné knihovny DLL.
Pokud je vyžadováno ověřování, měl by být příznak INTERNET_FLAG_KEEP_CONNECTION použit ve volání HttpOpenRequest. Příznak INTERNET_FLAG_KEEP_CONNECTION se vyžaduje pro protokol NTLM a další typy ověřování, aby se během procesu ověřování zachovalo připojení. Pokud připojení není zachováno, musí se proces ověřování restartovat pomocí proxy serveru nebo serveru.
Funkce InternetOpenUrl a HttpSendRequest úspěšně dokončeny i v případě, že je vyžadováno ověření. Rozdíl je, že data vrácená v hlavičkových souborech a InternetReadFile obdrží stránku HTML informující uživatele o stavovém kódu.
Registrace ověřovacích klíčů
INTERNET_OPEN_TYPE_PRECONFIG se podívá na hodnoty registru ProxyEnable, ProxyServera ProxyOverride. Tyto hodnoty jsou umístěny v části HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Nastavení internetu.
Pro jiná schémata ověřování než Základní musí být klíč přidán do registru v části HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Zabezpečení. Hodnota DWORD, Flags, by měla být nastavena s příslušnou hodnotou. Následující seznam ukazuje možné hodnoty pro Flags.
PLUGIN_AUTH_FLAGS_UNIQUE_CONTEXT_PER_TCPIP (hodnota=0x01)
Každý soket TCP/IP (Transmission Control Protocol/Internet Protocol) obsahuje jiný kontext. V opačném případě se pro každou šablonu adresy URL sféry nebo šablonu blokové adresy URL předá nový kontext.
PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI (hodnota=0x02)
Tato knihovna DLL dokáže zpracovat vlastní uživatelský vstup.
PLUGIN_AUTH_FLAGS_CAN_HANDLE_NO_PASSWD (hodnota=0x04)
Tato knihovna DLL může být schopná provést ověřování bez výzvy uživatele k zadání hesla.
PLUGIN_AUTH_FLAGS_NO_REALM (value=0x08)
Tato knihovna DLL nepoužívá standardní řetězec sféry HTTP. Všechna data, která se zdá být sférou, jsou data specifická pro schéma.
PLUGIN_AUTH_FLAGS_KEEP_ALIVE_NOT_REQUIRED (hodnota=0x10)
Tato knihovna DLL nevyžaduje trvalé připojení pro sekvenci výzva-odpověď.
Chcete-li například přidat ověřování NTLM, musí být klíč NTLM přidán do HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security. V části HKEY_LOCAL_MACHINE\SOFTWARE\aplikace Microsoft\Internet Explorer\Zabezpečení\NTLM, hodnota řetězce, DLLFilea hodnota DWORD příznakymusí být přidány. DLLFile musí být nastaveno na Winsspi.dlla příznaky musí být nastaveny na 0x08.
Ověřování serveru
Když server obdrží požadavek vyžadující ověření, server vrátí zprávu se stavovým kódem 401. V této zprávě by měl server obsahovat jednu nebo více hlaviček odpovědi WWW-Authenticate. Mezi tyto hlavičky patří metody ověřování, které má server k dispozici. WinINet zvolí první metodu, která rozpozná.
Základní ověřování poskytuje slabé zabezpečení, pokud se kanál nešifruje pomocí SSL nebo PCT.
Funkci InternetErrorDlg lze použít k získání uživatelského jména a dat hesla od uživatele, nebo lze navrhnout přizpůsobené uživatelské rozhraní k získání těchto dat.
Vlastní rozhraní může použít funkci InternetSetOption k nastavení INTERNET_OPTION_PASSWORD a INTERNET_OPTION_USERNAME hodnot a následnému opětovnému odeslání požadavku na server.
Ověřování proxy serveru
Když se klient pokusí použít proxy server, který vyžaduje ověření, vrátí proxy klientovi zprávu se stavovým kódem 407. V této zprávě by měl proxy obsahovat jednu nebo více Proxy-Authenticate hlaviček odpovědi. Mezi tyto hlavičky patří metody ověřování dostupné z proxy serveru. WinINet zvolí první metodu, která rozpozná.
Funkci InternetErrorDlg lze použít k získání uživatelského jména a hesla od uživatele nebo k návrhu přizpůsobeného uživatelského rozhraní.
Vlastní rozhraní může použít funkci InternetSetOption k nastavení INTERNET_OPTION_PROXY_PASSWORD a INTERNET_OPTION_PROXY_USERNAME hodnot a následnému opětovnému odeslání požadavku na proxy server.
Pokud nejsou nastavené žádné uživatelské jméno a heslo proxy serveru, pokusí se winINet použít uživatelské jméno a heslo pro server. Toto chování umožňuje klientům implementovat stejné přizpůsobené uživatelské rozhraní, které se používá ke zpracování ověřování serveru.
Zpracování ověřování HTTP
Ověřování HTTP je možné zpracovat pomocí InternetErrorDlg nebo vlastní funkce, která používá InternetSetOption nebo přidává vlastní hlavičky ověřování. InternetErrorDlg může prozkoumat hlavičky přidružené k HINTERNET, aby našel skryté chyby, jako jsou stavové kódy z proxy nebo serveru. InternetSetOption lze použít k nastavení uživatelského jména a hesla pro proxy server a server. Pro ověřování MSN a DPA musí být InternetErrorDlg použit k nastavení uživatelského jména a hesla.
U všech přizpůsobených funkcí, které přidávají vlastní hlavičky WWW-Authenticate nebo Proxy-Authenticate, by měl být příznak INTERNET_FLAG_NO_AUTH nastavený tak, aby se ověřování zakázalo.
Následující příklad ukazuje, jak InternetErrorDlg lze použít ke zpracování ověřování HTTP.
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.
V příkladu dwErrorCode slouží k ukládání všech chyb spojených s voláním HttpSendRequest. httpSendRequest úspěšně dokončen, i když proxy server nebo server vyžaduje ověření. Pokud je příznak FLAGS_ERROR_UI_FILTER_FOR_ERRORS předán InternetErrorDlg, funkce zkontroluje záhlaví pro jakékoli skryté chyby. Tyto skryté chyby by zahrnovaly všechny požadavky na ověření. InternetErrorDlg zobrazí příslušné dialogové okno s výzvou uživateli k zadání potřebných dat. Příznaky FLAGS_ERROR_UI_FLAGS_GENERATE_DATA a FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS by měly být předány také InternetErrorDlg, aby funkce vytvořila odpovídající datovou strukturu pro chybu a uloží výsledky dialogového okna v popisovači HINTERNET.
Následující příklad kódu ukazuje, jak ověřování lze zpracovat pomocí InternetSetOption.
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.
Poznámka
WinINet nepodporuje implementace serveru. Kromě toho by se nemělo používat v rámci služby. Pro implementace serverů nebo služby použijte microsoft Windows HTTP Services (WinHTTP).