WinHttpQueryAuthSchemes 関数 (winhttp.h)

WinHttpQueryAuthSchemes 関数は、サーバーでサポートされている承認スキームを返します。

構文

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

パラメーター

[in] hRequest

WinHttpOpenRequest によって返される有効な HINTERNET ハンドル

[out] lpdwSupportedSchemes

サポートされている認証スキームを含むフラグを指定する符号なし整数。 このパラメーターは、次の表で識別される 1 つ以上のフラグを返すことができます。

説明
WINHTTP_AUTH_SCHEME_BASIC
基本認証が使用可能であることを示します。
WINHTTP_AUTH_SCHEME_NTLM
NTLM 認証が使用可能であることを示します。
WINHTTP_AUTH_SCHEME_PASSPORT
パスポート認証が使用可能であることを示します。
WINHTTP_AUTH_SCHEME_DIGEST
ダイジェスト認証が使用可能であることを示します。
WINHTTP_AUTH_SCHEME_NEGOTIATE
NTLM 認証と Kerberos 認証を選択します。

[out] lpdwFirstScheme

サーバーによって一覧表示される最初の認証スキームを含むフラグを指定する符号なし整数。 このパラメーターは、次の表で識別される 1 つ以上のフラグを返すことができます。

説明
WINHTTP_AUTH_SCHEME_BASIC
基本認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_NTLM
NTLM 認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_PASSPORT
パスポート認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_DIGEST
ダイジェスト認証が最初であることを示します。
WINHTTP_AUTH_SCHEME_NEGOTIATE
NTLM 認証と Kerberos 認証を選択します。

[out] pdwAuthTarget

認証ターゲットを含むフラグを指定する符号なし整数。 このパラメーターは、次の表で識別される 1 つ以上のフラグを返すことができます。

説明
WINHTTP_AUTH_TARGET_SERVER
認証ターゲットはサーバーです。 401 状態コードが受信されたことを示します。
WINHTTP_AUTH_TARGET_PROXY
認証ターゲットはプロキシです。 407 状態コードが受信されたことを示します。

戻り値

成功した場合は TRUE 、失敗した場合 は FALSE を 返します。 詳細なエラー情報を得るには、GetLastError を呼び出します。 次の表は、返されるエラー コードを示しています。

エラー コード 説明
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
指定されたハンドルの種類が、この操作に対して正しくありません。
ERROR_WINHTTP_INTERNAL_ERROR
内部エラーが発生しました。
ERROR_NOT_ENOUGH_MEMORY
要求された操作を完了するのに十分なメモリが使用できませんでした。 (Windows エラー コード)

解説

WinHTTP が非同期モードで使用されている場合 (つまり、WinHttpOpenWINHTTP_FLAG_ASYNCが設定されている場合) でも、この関数は同期的に動作します。 戻り値は成功または失敗を示します。 詳細なエラー情報を得るには、GetLastError を呼び出します。

WinHttpQueryAuthSchemes は、 WinHttpQueryHeaders を呼び出す前に使用できません。

メモ Windows XP および Windows 2000 については、WinHttp スタート ページの 「ランタイム要件」 セクションを参照してください。
 

次の例は、認証が必要な場合に HTTP サーバーから指定されたドキュメントを取得する方法を示しています。 サーバーまたはプロキシが認証を要求しているかどうかを判断するために、状態コードが応答から取得されます。 200 の状態コードが見つかった場合は、ドキュメントを使用できます。 状態コード 401 または 407 が見つかった場合は、ドキュメントを取得する前に認証が必要です。 その他の状態コードの場合は、エラー メッセージが表示されます。

#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 );
}


要件

   
サポートされている最小のクライアント Windows XP、Windows 2000 Professional SP3 [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows Server 2003、Windows 2000 Server SP3 [デスクトップ アプリのみ]
対象プラットフォーム Windows
ヘッダー winhttp.h
Library Winhttp.lib
[DLL] Winhttp.dll
再頒布可能パッケージ Windows XP および Windows 2000 では、WinHTTP 5.0 およびインターネット エクスプローラー 5.01 以降がインストールされています。

関連項目

Microsoft Windows HTTP Services (WinHTTP) について

WinHTTP バージョン

WinHttpSetCredentials