다음을 통해 공유


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

지원되는 인증 체계를 포함하는 플래그를 지정하는 부호 없는 정수입니다. 이 매개 변수는 다음 표에서 식별되는 하나 이상의 플래그를 반환할 수 있습니다.

의미
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

서버에 나열된 첫 번째 인증 체계를 포함하는 플래그를 지정하는 부호 없는 정수입니다. 이 매개 변수는 다음 표에서 식별되는 하나 이상의 플래그를 반환할 수 있습니다.

의미
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

인증 대상이 포함된 플래그를 지정하는 부호 없는 정수입니다. 이 매개 변수는 다음 표에서 식별되는 하나 이상의 플래그를 반환할 수 있습니다.

의미
WINHTTP_AUTH_TARGET_SERVER
인증 대상은 서버입니다. 401 상태 코드가 수신되었음을 나타냅니다.
WINHTTP_AUTH_TARGET_PROXY
인증 대상은 프록시입니다. 407 상태 코드가 수신되었음을 나타냅니다.

반환 값

성공하면 TRUE 를 반환하고 실패하면 FALSE 를 반환합니다. 확장 오류 정보를 가져오려면 GetLastError를 호출합니다. 다음 표에서는 반환되는 오류 코드를 식별합니다.

오류 코드 Description
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
제공된 핸들의 형식이 이 작업에 잘못되었습니다.
ERROR_WINHTTP_INTERNAL_ERROR
내부 오류가 발생했습니다.
ERROR_NOT_ENOUGH_MEMORY
요청된 작업을 완료하는 데 사용할 수 있는 메모리가 부족합니다. (Windows 오류 코드)

설명

WinHTTP가 비동기 모드에서 사용되는 경우에도(즉, WinHttpOpen에서 WINHTTP_FLAG_ASYNC 설정된 경우) 이 함수는 동기적으로 작동합니다. 반환 값은 성공 또는 실패를 나타냅니다. 확장 오류 정보를 가져오려면 GetLastError를 호출합니다.

WinHttpQueryHeaders 를 호출하기 전에 WinHttpQueryAuthSchemes를 사용할 수 없습니다.

참고 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
라이브러리 Winhttp.lib
DLL Winhttp.dll
재배포 가능 파일 Windows XP 및 Windows 2000에서 WinHTTP 5.0 및 인터넷 Explorer 5.01 이상.

추가 정보

Microsoft Windows HTTP 서비스 정보(WinHTTP)

WinHTTP 버전

WinHttpSetCredentials