WinHttpQueryAuthSchemes-Funktion (winhttp.h)

Die WinHttpQueryAuthSchemes-Funktion gibt die Vom Server unterstützten Autorisierungsschemas zurück.

Syntax

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

Parameter

[in] hRequest

Gültiges HINTERNET-Handle, das von WinHttpOpenRequest zurückgegeben wird

[out] lpdwSupportedSchemes

Eine ganze Zahl ohne Vorzeichen, die ein Flag angibt, das die unterstützten Authentifizierungsschemas enthält. Dieser Parameter kann ein oder mehrere Flags zurückgeben, die in der folgenden Tabelle identifiziert sind.

Wert Bedeutung
WINHTTP_AUTH_SCHEME_BASIC
Gibt an, dass die Standardauthentifizierung verfügbar ist.
WINHTTP_AUTH_SCHEME_NTLM
Gibt an, dass die NTLM-Authentifizierung verfügbar ist.
WINHTTP_AUTH_SCHEME_PASSPORT
Gibt an, dass die Passauthentifizierung verfügbar ist.
WINHTTP_AUTH_SCHEME_DIGEST
Gibt an, dass die Digestauthentifizierung verfügbar ist.
WINHTTP_AUTH_SCHEME_NEGOTIATE
Wählt zwischen NTLM- und Kerberos-Authentifizierung aus.

[out] lpdwFirstScheme

Eine ganze Zahl ohne Vorzeichen, die ein Flag angibt, das das erste vom Server aufgeführte Authentifizierungsschema enthält. Dieser Parameter kann ein oder mehrere Flags zurückgeben, die in der folgenden Tabelle identifiziert sind.

Wert Bedeutung
WINHTTP_AUTH_SCHEME_BASIC
Gibt an, dass die Standardauthentifizierung zuerst erfolgt.
WINHTTP_AUTH_SCHEME_NTLM
Gibt an, dass die NTLM-Authentifizierung zuerst erfolgt.
WINHTTP_AUTH_SCHEME_PASSPORT
Gibt an, dass die Passauthentifizierung zuerst erfolgt.
WINHTTP_AUTH_SCHEME_DIGEST
Gibt an, dass die Digestauthentifizierung zuerst erfolgt.
WINHTTP_AUTH_SCHEME_NEGOTIATE
Wählt zwischen NTLM- und Kerberos-Authentifizierung aus.

[out] pdwAuthTarget

Eine ganze Zahl ohne Vorzeichen, die ein Flag angibt, das das Authentifizierungsziel enthält. Dieser Parameter kann ein oder mehrere Flags zurückgeben, die in der folgenden Tabelle identifiziert sind.

Wert Bedeutung
WINHTTP_AUTH_TARGET_SERVER
Das Authentifizierungsziel ist ein Server. Gibt an, dass ein 401-status-Code empfangen wurde.
WINHTTP_AUTH_TARGET_PROXY
Das Authentifizierungsziel ist ein Proxy. Gibt an, dass ein 407-status-Code empfangen wurde.

Rückgabewert

Gibt TRUE zurück, wenn erfolgreich, oder FALSE , wenn nicht erfolgreich. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf. In der folgenden Tabelle werden die zurückgegebenen Fehlercodes angegeben.

Fehlercode BESCHREIBUNG
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
Der Typ des angegebenen Handles ist für diesen Vorgang falsch.
ERROR_WINHTTP_INTERNAL_ERROR
Ein interner Fehler ist aufgetreten.
ERROR_NOT_ENOUGH_MEMORY
Für den angeforderten Vorgang war nicht genügend Arbeitsspeicher verfügbar. (Windows-Fehlercode)

Hinweise

Auch wenn WinHTTP im asynchronen Modus verwendet wird (d. h. wenn WINHTTP_FLAG_ASYNC in WinHttpOpen festgelegt ist), wird diese Funktion synchron ausgeführt. Der Rückgabewert weist auf Erfolg oder Fehler hin. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

WinHttpQueryAuthSchemes kann vor dem Aufrufen von WinHttpQueryHeaders nicht verwendet werden.

Hinweis Informationen zu Windows XP und Windows 2000 finden Sie im Abschnitt Laufzeitanforderungen der WinHttp-Startseite .
 

Beispiele

Das folgende Beispiel zeigt, wie ein angegebenes Dokument von einem HTTP-Server abgerufen wird, wenn eine Authentifizierung erforderlich ist. Der status Code wird aus der Antwort abgerufen, um zu bestimmen, ob der Server oder Proxy die Authentifizierung anfordert. Wenn ein Code mit 200 status gefunden wird, ist das Dokument verfügbar. Wenn ein status Code 401 oder 407 gefunden wird, ist eine Authentifizierung erforderlich, bevor das Dokument abgerufen werden kann. Für alle anderen status Code wird eine Fehlermeldung angezeigt.

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


Anforderungen

   
Unterstützte Mindestversion (Client) Windows XP, Windows 2000 Professional mit SP3 [nur Desktop-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003, Windows 2000 Server mit SP3 [nur Desktop-Apps]
Zielplattform Windows
Kopfzeile winhttp.h
Bibliothek Winhttp.lib
DLL Winhttp.dll
Verteilbare Komponente WinHTTP 5.0 und Internet Explorer 5.01 oder höher unter Windows XP und Windows 2000.

Weitere Informationen

Informationen zu Microsoft Windows HTTP-Diensten (WinHTTP)

WinHTTP-Versionen

WinHttpSetCredentials