Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Gdy klient i serwer negocjują połączenie HTTPS, najpierw należy ustanowić połączenie TLS. W ramach uzgadniania TLS klient wysyła nazwę domeny serwera, do którego się łączy, w jednym z rozszerzeń TLS. Jeśli na tej samej maszynie jest hostowanych wiele (wirtualnych) serwerów, ta funkcja protokołu TLS umożliwia klientom odróżnienie serwerów, z którymi się łączą, i skonfigurowanie ustawień protokołu TLS, takich jak certyfikat serwera, odpowiednio.
Po utworzeniu żądania HTTP przy użyciu HttpClient
implementacja automatycznie wybiera wartość rozszerzenia oznaczania nazwy serwera (SNI) na podstawie adresu URL, z którym nawiązuje połączenie klient. W przypadku scenariuszy wymagających większej ręcznej kontroli nad rozszerzeniem można użyć jednego z następujących podejść.
Nagłówek hosta
Nagłówek HTTP hosta wykonuje podobną funkcję jak rozszerzenie SNI w protokole TLS. Dzięki temu serwer docelowy może rozróżniać żądania dla wielu nazw hostów na jednym adresie IP.
HttpClient
automatycznie wypełnia nagłówek Host przy użyciu identyfikatora URI żądania. Można jednak również ręcznie ustawić jej wartość, a HttpClient
także użyć nowej wartości w rozszerzeniu SNI. Możesz użyć metody HttpRequestMessage.Headers.Host
lub HttpClient.DefaultRequestHeaders.Host
, aby osiągnąć ten efekt.
using HttpClient client = new();
client.DefaultRequestHeaders.Host = "www.microsoft.com";
using var response = await client.GetAsync("https://127.0.0.1:5001/");
System.Console.WriteLine(response);
Uwaga / Notatka
Ta metoda nie umożliwia całkowitego uniknięcia wysyłania SNI podczas nawiązywania połączenia z adresem URL zawierającym nazwę hosta. Jeśli nagłówek jest ustawiony na pusty ciąg, HttpClient
zamiast tego użyje nazwy hosta z adresu URL.
Uwaga / Notatka
Dostosowywanie nagłówka hosta wpływa na walidację certyfikatu serwera. Domyślnie klient będzie oczekiwać, że certyfikat serwera będzie zgodny z nazwą hosta w nagłówku Host.
Ręczna autoryzacja SslStream za pomocą metody ConnectCallback
Bardziej skomplikowaną, ale również bardziej zaawansowaną opcją jest użycie elementu SocketsHttpHandler.ConnectCallback
. Od wersji .NET 7, możliwe jest zwrócenie uwierzytelnionego elementu SslStream
, co umożliwia dostosowanie sposobu nawiązywania połączenia TLS. Wewnątrz wywołania zwrotnego można użyć dowolnych SslClientAuthenticationOptions
opcji do przeprowadzenia uwierzytelniania po stronie klienta.
var handler = new SocketsHttpHandler
{
ConnectCallback = async (context, cancellationToken) =>
{
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true };
try
{
await socket.ConnectAsync(context.DnsEndPoint, cancellationToken);
var sslStream = new SslStream(new NetworkStream(socket, ownsSocket: true));
// When using HTTP/2, you must also keep in mind to set options like ApplicationProtocols
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
{
TargetHost = context.DnsEndPoint.Host,
}, cancellationToken);
return sslStream;
}
catch
{
socket.Dispose();
throw;
}
}
};
using HttpClient client = new(handler);
using var response = await client.GetAsync("https://www.microsoft.com");
System.Console.WriteLine(response);