Bagikan melalui


Fungsi WinHttpQueryAuthSchemes (winhttp.h)

Fungsi WinHttpQueryAuthSchemes mengembalikan skema otorisasi yang didukung oleh server.

Sintaks

WINHTTPAPI BOOL WinHttpQueryAuthSchemes(
  [in]  HINTERNET hRequest,
  [out] LPDWORD   lpdwSupportedSchemes,
  [out] LPDWORD   lpdwFirstScheme,
  [out] LPDWORD   pdwAuthTarget
);

Parameter

[in] hRequest

Handel HINTERNET yang valid dikembalikan oleh WinHttpOpenRequest

[out] lpdwSupportedSchemes

Bilangan bulat yang tidak ditandatangani yang menentukan bendera yang berisi skema autentikasi yang didukung. Parameter ini dapat mengembalikan satu atau beberapa bendera yang diidentifikasi dalam tabel berikut.

Nilai Makna
WINHTTP_AUTH_SCHEME_BASIC
Menunjukkan autentikasi dasar tersedia.
WINHTTP_AUTH_SCHEME_NTLM
Menunjukkan autentikasi NTLM tersedia.
WINHTTP_AUTH_SCHEME_PASSPORT
Menunjukkan autentikasi paspor tersedia.
WINHTTP_AUTH_SCHEME_DIGEST
Menunjukkan autentikasi hash tersedia.
WINHTTP_AUTH_SCHEME_NEGOTIATE
Memilih antara autentikasi NTLM dan Kerberos.

[out] lpdwFirstScheme

Bilangan bulat yang tidak ditandatangani yang menentukan bendera yang berisi skema autentikasi pertama yang tercantum oleh server. Parameter ini dapat mengembalikan satu atau beberapa bendera yang diidentifikasi dalam tabel berikut.

Nilai Makna
WINHTTP_AUTH_SCHEME_BASIC
Menunjukkan autentikasi dasar adalah yang pertama.
WINHTTP_AUTH_SCHEME_NTLM
Menunjukkan autentikasi NTLM adalah yang pertama.
WINHTTP_AUTH_SCHEME_PASSPORT
Menunjukkan autentikasi paspor adalah yang pertama.
WINHTTP_AUTH_SCHEME_DIGEST
Menunjukkan autentikasi hash adalah yang pertama.
WINHTTP_AUTH_SCHEME_NEGOTIATE
Memilih antara autentikasi NTLM dan Kerberos.

[out] pdwAuthTarget

Bilangan bulat yang tidak ditandatangani yang menentukan bendera yang berisi target autentikasi. Parameter ini dapat mengembalikan satu atau beberapa bendera yang diidentifikasi dalam tabel berikut.

Nilai Makna
WINHTTP_AUTH_TARGET_SERVER
Target autentikasi adalah server. Menunjukkan bahwa kode status 401 telah diterima.
WINHTTP_AUTH_TARGET_PROXY
Target autentikasi adalah proksi. Menunjukkan bahwa kode status 407 telah diterima.

Nilai kembali

Mengembalikan TRUE jika berhasil, atau FALSE jika tidak berhasil. Untuk mendapatkan informasi kesalahan yang diperluas, hubungi GetLastError. Tabel berikut mengidentifikasi kode kesalahan yang dikembalikan.

Kode Kesalahan Deskripsi
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
Jenis handel yang disediakan salah untuk operasi ini.
ERROR_WINHTTP_INTERNAL_ERROR
Terjadi kesalah internal.
ERROR_NOT_ENOUGH_MEMORY
Tidak tersedia cukup memori untuk menyelesaikan operasi yang diminta. (Kode galat Windows)

Keterangan

Bahkan ketika WinHTTP digunakan dalam mode asinkron (yaitu, ketika WINHTTP_FLAG_ASYNC diatur di WinHttpOpen), fungsi ini beroperasi secara sinkron. Nilai yang dikembalikan menunjukkan keberhasilan atau kegagalan. Untuk mendapatkan informasi kesalahan yang diperluas, hubungi GetLastError.

WinHttpQueryAuthSchemes tidak dapat digunakan sebelum memanggil WinHttpQueryHeaders.

Catatan Untuk Windows XP dan Windows 2000 lihat bagian Persyaratan Run-Time di halaman mulai WinHttp.
 

Contoh

Contoh berikut menunjukkan cara mengambil dokumen tertentu dari server HTTP saat autentikasi diperlukan. Kode status diambil dari respons untuk menentukan apakah server atau proksi meminta autentikasi. Jika kode status 200 ditemukan, dokumen tersedia. Jika kode status 401 atau 407 ditemukan, autentikasi diperlukan sebelum dokumen dapat diambil. Untuk kode status lainnya, pesan kesalahan ditampilkan.

#include <windows.h>
#include <winhttp.h>
#include <stdio.h>

#pragma comment(lib, "winhttp.lib")

DWORD ChooseAuthScheme( DWORD dwSupportedSchemes )
{
  //  It is the server's responsibility only to accept 
  //  authentication schemes that provide a sufficient level
  //  of security to protect the server's resources.
  //
  //  The client is also obligated only to use an authentication
  //  scheme that adequately protects its username and password.
  //
  //  Thus, this sample code does not use Basic authentication  
  //  because Basic authentication exposes the client's username 
  //  and password to anyone monitoring the connection.
  
  if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NEGOTIATE )
    return WINHTTP_AUTH_SCHEME_NEGOTIATE;
  else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NTLM )
    return WINHTTP_AUTH_SCHEME_NTLM;
  else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_PASSPORT )
    return WINHTTP_AUTH_SCHEME_PASSPORT;
  else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_DIGEST )
    return WINHTTP_AUTH_SCHEME_DIGEST;
  else
    return 0;
}

struct SWinHttpSampleGet
{
  LPCWSTR szServer;
  LPCWSTR szPath;
  BOOL fUseSSL;
  LPCWSTR szServerUsername;
  LPCWSTR szServerPassword;
  LPCWSTR szProxyUsername;
  LPCWSTR szProxyPassword;
};

void WinHttpAuthSample( IN SWinHttpSampleGet *pGetRequest )
{
  DWORD dwStatusCode = 0;
  DWORD dwSupportedSchemes;
  DWORD dwFirstScheme;
  DWORD dwSelectedScheme;
  DWORD dwTarget;
  DWORD dwLastStatus = 0;
  DWORD dwSize = sizeof(DWORD);
  BOOL  bResults = FALSE;
  BOOL  bDone = FALSE;

  DWORD dwProxyAuthScheme = 0;
  HINTERNET  hSession = NULL, 
             hConnect = NULL,
             hRequest = NULL;

  // Use WinHttpOpen to obtain a session handle.
  hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                          WINHTTP_NO_PROXY_NAME, 
                          WINHTTP_NO_PROXY_BYPASS, 0 );

  INTERNET_PORT nPort = ( pGetRequest->fUseSSL ) ? 
                        INTERNET_DEFAULT_HTTPS_PORT  :
                        INTERNET_DEFAULT_HTTP_PORT;

  // Specify an HTTP server.
  if( hSession )
    hConnect = WinHttpConnect( hSession, 
                               pGetRequest->szServer, 
                               nPort, 0 );

  // Create an HTTP request handle.
  if( hConnect )
    hRequest = WinHttpOpenRequest( hConnect, 
                                   L"GET", 
                                   pGetRequest->szPath,
                                   NULL, 
                                   WINHTTP_NO_REFERER, 
                                   WINHTTP_DEFAULT_ACCEPT_TYPES,
                                   ( pGetRequest->fUseSSL ) ? 
                                       WINHTTP_FLAG_SECURE : 0 );

  // Continue to send a request until status code is not 401 or 407.
  if( hRequest == NULL )
    bDone = TRUE;

  while( !bDone )
  {
    //  If a proxy authentication challenge was responded to, reset 
    //  those credentials before each SendRequest, because the proxy  
    //  may require re-authentication after responding to a 401 or to 
    //  a redirect. If you don't, you can get into a 407-401-407-401
    //  loop.
    if( dwProxyAuthScheme != 0 )
      bResults = WinHttpSetCredentials( hRequest, 
                                        WINHTTP_AUTH_TARGET_PROXY, 
                                        dwProxyAuthScheme, 
                                        pGetRequest->szProxyUsername,
                                        pGetRequest->szProxyPassword,
                                        NULL );
    // Send a request.
    bResults = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS,
                                   0,
                                   WINHTTP_NO_REQUEST_DATA,
                                   0, 
                                   0, 
                                   0 );

    // End the request.
    if( bResults )
      bResults = WinHttpReceiveResponse( hRequest, NULL );

    // Resend the request in case of 
    // ERROR_WINHTTP_RESEND_REQUEST error.
    if( !bResults && GetLastError( ) == ERROR_WINHTTP_RESEND_REQUEST)
        continue;

    // Check the status code.
    if( bResults ) 
      bResults = WinHttpQueryHeaders( hRequest, 
                                      WINHTTP_QUERY_STATUS_CODE | 
                                          WINHTTP_QUERY_FLAG_NUMBER,
                                      NULL, 
                                      &dwStatusCode, 
                                      &dwSize, 
                                      NULL );

    if( bResults )
    {
      switch( dwStatusCode )
      {
        case 200: 
          // The resource was successfully retrieved.
          // You can use WinHttpReadData to read the contents 
          // of the server's response.
          printf( "The resource was successfully retrieved.\n" );
          bDone = TRUE;
          break;

        case 401:
          // The server requires authentication.
          printf(
           "The server requires authentication. Sending credentials\n");

          // Obtain the supported and preferred schemes.
          bResults = WinHttpQueryAuthSchemes( hRequest, 
                                              &dwSupportedSchemes, 
                                              &dwFirstScheme, 
                                              &dwTarget );

          // Set the credentials before re-sending the request.
          if( bResults )
          {
            dwSelectedScheme = ChooseAuthScheme( dwSupportedSchemes );

            if( dwSelectedScheme == 0 )
              bDone = TRUE;
            else
              bResults = WinHttpSetCredentials( 
                                        hRequest, dwTarget, 
                                        dwSelectedScheme,
                                        pGetRequest->szServerUsername,
                                        pGetRequest->szServerPassword,
                                        NULL );
          }

          // If the same credentials are requested twice, abort the
          // request.  For simplicity, this sample does not check for
          // a repeated sequence of status codes.
          if( dwLastStatus == 401 )
            bDone = TRUE;

          break;

        case 407:
          // The proxy requires authentication.
          printf( 
           "The proxy requires authentication. Sending credentials\n");

          // Obtain the supported and preferred schemes.
          bResults = WinHttpQueryAuthSchemes( hRequest, 
                                              &dwSupportedSchemes, 
                                              &dwFirstScheme, 
                                              &dwTarget );

          // Set the credentials before re-sending the request.
          if( bResults )
            dwProxyAuthScheme = ChooseAuthScheme(dwSupportedSchemes);

          // If the same credentials are requested twice, abort the
          // request.  For simplicity, this sample does not check for
          // a repeated sequence of status codes.
          if( dwLastStatus == 407 )
            bDone = TRUE;
          break;

        default:
          // The status code does not indicate success.
          printf( "Error. Status code %d returned.\n", dwStatusCode );
          bDone = TRUE;
      }
    }

    // Keep track of the last status code.
    dwLastStatus = dwStatusCode;

    // If there are any errors, break out of the loop.
    if( !bResults ) 
        bDone = TRUE;
  }

  // Report any errors.
  if( !bResults )
  {
    DWORD dwLastError = GetLastError( );
    printf( "Error %d has occurred.\n", dwLastError );
  }

  // Close any open handles.
  if( hRequest ) WinHttpCloseHandle( hRequest );
  if( hConnect ) WinHttpCloseHandle( hConnect );
  if( hSession ) WinHttpCloseHandle( hSession );
}


Persyaratan

   
Klien minimum yang didukung Windows XP, Windows 2000 Professional dengan SP3 [hanya aplikasi desktop]
Server minimum yang didukung Windows Server 2003, Windows 2000 Server dengan SP3 [hanya aplikasi desktop]
Target Platform Windows
Header winhttp.h
Pustaka Winhttp.lib
DLL Winhttp.dll
Redistribusi WinHTTP 5.0 dan Internet Explorer 5.01 atau yang lebih baru di Windows XP dan Windows 2000.

Lihat juga

Tentang Microsoft Windows HTTP Services (WinHTTP)

Versi WinHTTP

WinHttpSetCredentials