Bagikan melalui


Menangani Autentikasi

Beberapa proksi dan server memerlukan autentikasi sebelum memberikan akses ke sumber daya di Internet. Fungsi WinINet mendukung server dan autentikasi proksi untuk sesi http. Autentikasi server ftp harus ditangani oleh fungsi InternetConnect . Saat ini, autentikasi gateway FTP tidak didukung.

Tentang Autentikasi HTTP

Jika autentikasi diperlukan, aplikasi klien menerima kode status 401, jika server memerlukan autentikasi, atau 407, jika proksi memerlukan autentikasi. Dengan kode status, proksi atau server mengirimkan satu, atau lebih, mengautentikasi header respons—Proxy-Authenticate (untuk autentikasi proksi) atau WWW-Authenticate (untuk autentikasi server).

Setiap header respons autentikasi berisi skema autentikasi dan realm yang tersedia. Jika beberapa skema autentikasi didukung, server mengembalikan beberapa header respons autentikasi. Nilai realm peka huruf besar/kecil dan mendefinisikan ruang perlindungan pada proksi atau server. Misalnya, header "WWW-Authenticate: Basic Realm="example"" akan menjadi contoh header yang dikembalikan saat autentikasi server diperlukan.

Aplikasi klien yang mengirim permintaan dapat mengautentikasi dirinya sendiri dengan menyertakan bidang header Otorisasi dengan permintaan. Header Otorisasi akan berisi skema autentikasi dan respons yang sesuai yang diperlukan oleh skema tersebut. Misalnya, header "Otorisasi: Nama pengguna:kata sandi> dasar<" akan ditambahkan ke permintaan dan dikirim ulang ke server jika klien menerima header respons autentikasi "WWW-Authenticate: Basic Realm="example"".

Ada dua jenis umum skema autentikasi:

  • Skema autentikasi dasar, tempat nama pengguna dan kata sandi dikirim dalam teks jelas ke server.
  • Skema respons tantangan, yang memungkinkan format respons tantangan.

Skema autentikasi Dasar didasarkan pada model yang harus diautentikasi klien itu sendiri dengan nama pengguna dan kata sandi untuk setiap realm. Server melayani permintaan jika ditolak dengan header Otorisasi yang menyertakan nama pengguna dan kata sandi yang valid.

Skema respons tantangan memungkinkan autentikasi yang lebih aman. Jika permintaan memerlukan autentikasi menggunakan skema respons tantangan, kode status yang sesuai dan Header autentikasi dikembalikan ke klien. Klien kemudian harus mengirim ulang permintaan dengan negosiasi. Server akan mengembalikan kode status yang sesuai dengan tantangan, dan klien kemudian harus mengirim ulang permintaan dengan respons yang tepat untuk mendapatkan layanan yang diminta.

Tabel berikut ini mencantumkan skema autentikasi, jenis autentikasi, DLL yang mendukungnya, dan deskripsi skema.

Skema Jenis DLL Deskripsi
Dasar (cleartext) Dasar Wininet.dll Menggunakan string yang dikodekan base64 yang berisi nama pengguna dan kata sandi.
digest respons tantangan Digest.dll Skema respons tantangan yang menantang menggunakan nilai nonce (string data yang ditentukan server). Respons yang valid berisi checksum nama pengguna, kata sandi, nilai nonce yang diberikan, metode HTTP, dan Pengidentifikasi Sumber Daya Seragam (URI) yang diminta. Dukungan autentikasi hash diperkenalkan di Microsoft Internet Explorer 5.
Manajer LAN NT (NTLM) respons tantangan Winsspi.dll Skema respons tantangan yang mendasarkan tantangan pada nama pengguna.
Microsoft Network (MSN) respons tantangan Msnsspc.dll Skema autentikasi Microsoft Network.
Autentikasi Kata Sandi Terdistribusi (DPA) respons tantangan Msapsspc.dll Mirip dengan autentikasi MSN dan juga digunakan oleh Microsoft Network.
Autentikasi Frase Sandi Jarak Jauh (RPA) Compuserve Rpawinet.dll, da.dll Skema autentikasi CompuServe. Untuk informasi selengkapnya, lihat Spesifikasi Mekanisme RPA.

 

Untuk apa pun selain autentikasi Dasar, kunci registri harus disiapkan selain menginstal DLL yang sesuai.

Jika autentikasi diperlukan, bendera INTERNET_FLAG_KEEP_CONNECTION harus digunakan dalam panggilan ke HttpOpenRequest. Bendera INTERNET_FLAG_KEEP_CONNECTION diperlukan untuk NTLM dan jenis autentikasi lainnya untuk mempertahankan koneksi saat menyelesaikan proses autentikasi. Jika koneksi tidak dipertahankan, proses autentikasi harus dimulai ulang dengan proksi atau server.

Fungsi InternetOpenUrl dan HttpSendRequest berhasil diselesaikan bahkan ketika autentikasi diperlukan. Perbedaannya adalah, data yang dikembalikan dalam file header dan InternetReadFile akan menerima halaman HTML yang memberi tahu pengguna tentang kode status.

Mendaftarkan Kunci Autentikasi

INTERNET_OPEN_TYPE_PRECONFIG melihat nilai registri ProxyEnable, ProxyServer, dan ProxyOverride. Nilai-nilai ini terletak di HKEY_CURRENT_USER\Pengaturan InternetMicrosoft\Windows\CurrentVersion\Perangkat Lunak\.

Untuk skema autentikasi selain Dasar, kunci harus ditambahkan ke registri di bawah HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security. Nilai DWORD , Bendera, harus diatur dengan nilai yang sesuai. Daftar berikut ini memperlihatkan nilai yang mungkin untuk nilai Bendera .

  • PLUGIN_AUTH_FLAGS_UNIQUE_CONTEXT_PER_TCPIP (value=0x01)

    Setiap soket Protokol Kontrol Transmisi/Protokol Internet (TCP/IP) berisi konteks yang berbeda. Jika tidak, konteks baru diteruskan untuk setiap realm atau templat URL blok.

  • PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI (value=0x02)

    DLL ini dapat menangani input penggunanya sendiri.

  • PLUGIN_AUTH_FLAGS_CAN_HANDLE_NO_PASSWD (value=0x04)

    DLL ini mungkin mampu melakukan autentikasi tanpa meminta kata sandi kepada pengguna.

  • PLUGIN_AUTH_FLAGS_NO_REALM (value=0x08)

    DLL ini tidak menggunakan string realm http standar. Data apa pun yang tampaknya merupakan realm adalah data khusus skema.

  • PLUGIN_AUTH_FLAGS_KEEP_ALIVE_NOT_REQUIRED (value=0x10)

    DLL ini tidak memerlukan koneksi persisten untuk urutan respons tantangannya.

Misalnya, untuk menambahkan autentikasi NTLM, kunci NTLM harus ditambahkan ke HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security. Di bawah HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security\NTLM, nilai string, DLLFile, dan nilai DWORD , Bendera, harus ditambahkan. DLLFile harus diatur ke Winsspi.dll, dan Bendera harus diatur ke 0x08.

Autentikasi Server

Ketika server menerima permintaan yang memerlukan autentikasi, server mengembalikan pesan kode status 401. Dalam pesan itu, server harus menyertakan satu atau beberapa header respons WWW-Authenticate. Header ini mencakup metode autentikasi yang tersedia server. WinINet memilih metode pertama yang dikenalinya.

Autentikasi dasar memberikan keamanan yang lemah kecuali saluran dienkripsi tautan pertama dengan SSL atau PCT.

Fungsi InternetErrorDlg dapat digunakan untuk mendapatkan data nama pengguna dan kata sandi dari pengguna, atau antarmuka pengguna yang disesuaikan dapat dirancang untuk mendapatkan data.

Antarmuka kustom dapat menggunakan fungsi InternetSetOption untuk mengatur nilai INTERNET_OPTION_PASSWORD dan INTERNET_OPTION_USERNAME lalu mengirim ulang permintaan ke server.

Autentikasi Proksi

Ketika klien mencoba menggunakan proksi yang memerlukan autentikasi, proksi mengembalikan pesan kode status 407 ke klien. Dalam pesan itu, proksi harus menyertakan satu atau beberapa header respons Proxy-Authenticate. Header ini mencakup metode autentikasi yang tersedia dari proksi. WinINet memilih metode pertama yang dikenalinya.

Fungsi InternetErrorDlg dapat digunakan untuk mendapatkan data nama pengguna dan kata sandi dari pengguna, atau antarmuka pengguna yang disesuaikan dapat dirancang.

Antarmuka kustom dapat menggunakan fungsi InternetSetOption untuk mengatur nilai INTERNET_OPTION_PROXY_PASSWORD dan INTERNET_OPTION_PROXY_USERNAME lalu mengirim ulang permintaan ke proksi.

Jika tidak ada nama pengguna dan kata sandi proksi yang diatur, WinINet mencoba menggunakan nama pengguna dan kata sandi untuk server. Perilaku ini memungkinkan klien untuk mengimplementasikan antarmuka pengguna yang disesuaikan yang sama yang digunakan untuk menangani autentikasi server.

Menangani Autentikasi HTTP

Autentikasi HTTP dapat ditangani dengan InternetErrorDlg atau fungsi yang disesuaikan yang menggunakan InternetSetOption atau menambahkan header autentikasinya sendiri. InternetErrorDlg dapat memeriksa header yang terkait dengan handel HINTERNET untuk menemukan kesalahan tersembunyi, seperti kode status dari proksi atau server. InternetSetOption dapat digunakan untuk mengatur nama pengguna dan kata sandi untuk proksi dan server. Untuk autentikasi MSN dan DPA, InternetErrorDlg harus digunakan untuk mengatur nama pengguna dan kata sandi.

Untuk fungsi kustomisasi apa pun yang menambahkan header WWW-Authenticate atau Proxy-Authenticate sendiri, bendera INTERNET_FLAG_NO_AUTH harus diatur untuk menonaktifkan autentikasi.

Contoh berikut menunjukkan bagaimana InternetErrorDlg dapat digunakan untuk menangani autentikasi 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.

Dalam contoh, dwErrorCode digunakan untuk menyimpan kesalahan apa pun yang terkait dengan panggilan ke HttpSendRequest. HttpSendRequest berhasil diselesaikan, bahkan jika proksi atau server memerlukan autentikasi. Ketika bendera FLAGS_ERROR_UI_FILTER_FOR_ERRORS diteruskan ke InternetErrorDlg, fungsi memeriksa header untuk setiap kesalahan tersembunyi. Kesalahan tersembunyi ini akan mencakup permintaan autentikasi apa pun. InternetErrorDlg menampilkan kotak dialog yang sesuai untuk meminta data yang diperlukan kepada pengguna. Bendera FLAGS_ERROR_UI_FLAGS_GENERATE_DATA dan FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS juga harus diteruskan ke InternetErrorDlg, sehingga fungsi membangun struktur data yang sesuai untuk kesalahan dan menyimpan hasil kotak dialog dalam handel HINTERNET .

Contoh kode berikut menunjukkan bagaimana autentikasi dapat ditangani menggunakan 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.

Catatan

WinINet tidak mendukung implementasi server. Selain itu, itu tidak boleh digunakan dari layanan. Untuk implementasi atau layanan server, gunakan Microsoft Windows HTTP Services (WinHTTP).