Funzione WinHttpQueryAuthSchemes (winhttp.h)
La funzione WinHttpQueryAuthSchemes restituisce gli schemi di autorizzazione supportati dal server.
Sintassi
WINHTTPAPI BOOL WinHttpQueryAuthSchemes(
[in] HINTERNET hRequest,
[out] LPDWORD lpdwSupportedSchemes,
[out] LPDWORD lpdwFirstScheme,
[out] LPDWORD pdwAuthTarget
);
Parametri
[in] hRequest
Handle HINTERNET valido restituito da WinHttpOpenRequest
[out] lpdwSupportedSchemes
Intero senza segno che specifica un flag che contiene gli schemi di autenticazione supportati. Questo parametro può restituire uno o più flag identificati nella tabella seguente.
[out] lpdwFirstScheme
Intero senza segno che specifica un flag contenente il primo schema di autenticazione elencato dal server. Questo parametro può restituire uno o più flag identificati nella tabella seguente.
[out] pdwAuthTarget
Intero senza segno che specifica un flag contenente la destinazione di autenticazione. Questo parametro può restituire uno o più flag identificati nella tabella seguente.
Valore restituito
Restituisce TRUE se ha esito positivo o FALSE se ha esito negativo. Per informazioni dettagliate sull'errore, chiamare GetLastError. La tabella seguente identifica i codici di errore restituiti.
Codice di errore | Descrizione |
---|---|
|
Il tipo di handle fornito non è corretto per questa operazione. |
|
Si è verificato un errore interno. |
|
Memoria insufficiente per completare l'operazione richiesta. (Codice errore di Windows) |
Commenti
Anche quando WinHTTP viene usato in modalità asincrona, ovvero quando WINHTTP_FLAG_ASYNC è impostato in WinHttpOpen, questa funzione opera in modo sincrono. Il valore restituito indica l'esito positivo o negativo. Per informazioni dettagliate sull'errore, chiamare GetLastError.
WinHttpQueryAuthSchemes non può essere usato prima di chiamare WinHttpQueryHeaders.
Esempio
Nell'esempio seguente viene illustrato come recuperare un documento specificato da un server HTTP quando è necessaria l'autenticazione. Il codice di stato viene recuperato dalla risposta per determinare se il server o il proxy richiede l'autenticazione. Se viene trovato un codice di stato 200, il documento è disponibile. Se viene trovato un codice di stato 401 o 407, è necessaria l'autenticazione prima che sia possibile recuperare il documento. Per qualsiasi altro codice di stato viene visualizzato un messaggio di errore.
#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 );
}
Requisiti
Client minimo supportato | Windows XP, Windows 2000 Professional con SP3 [solo app desktop] |
Server minimo supportato | Windows Server 2003, Windows 2000 Server con SP3 [solo app desktop] |
Piattaforma di destinazione | Windows |
Intestazione | winhttp.h |
Libreria | Winhttp.lib |
DLL | Winhttp.dll |
Componente ridistribuibile | WinHTTP 5.0 e Internet Explorer 5.01 o versione successiva in Windows XP e Windows 2000. |