Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn ein Client und server eine HTTPS-Verbindung aushandeln, muss zuerst eine TLS-Verbindung hergestellt werden. Im Rahmen des TLS-Handshakes sendet der Client den Domänennamen des Servers, mit dem er in einer der TLS-Erweiterungen verbunden ist. Wenn mehrere (virtuelle) Server auf demselben Computer gehostet werden, ermöglicht dieses Feature des TLS-Protokolls Clients, zu unterscheiden, mit welchen dieser Server sie eine Verbindung herstellen, und um TLS-Einstellungen wie das Serverzertifikat entsprechend zu konfigurieren.
Wenn eine HTTP-Anforderung mit HttpClient verwendet wird, wählt die Implementierung automatisch einen Wert für die SNI-Erweiterung (Server Name Indication) basierend auf der URL aus, mit der der Client eine Verbindung herstellt. Für Szenarien, die eine manuelle Steuerung der Erweiterung erfordern, können Sie einen der folgenden Ansätze verwenden.
Hostheader
Host-HTTP-Header führt eine ähnliche Funktion wie die SNI-Erweiterung in TLS aus. Dadurch kann der Zielserver zwischen Anforderungen für mehrere Hostnamen in einer einzelnen IP-Adresse unterscheiden.
HttpClient füllt den Hostheader automatisch mithilfe des Anforderungs-URI aus. Sie können den Wert jedoch auch manuell festlegen und HttpClient auch den neuen Wert in der SNI-Erweiterung verwenden. Sie können entweder HttpRequestMessage.Headers.Host oder HttpClient.DefaultRequestHeaders.Host verwenden, um diesen Effekt zu erzielen.
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);
Hinweis
Mit dieser Methode können Sie nicht verhindern, dass SNI vollständig gesendet wird, wenn Sie eine Verbindung mit einer URL mit einem Hostnamen herstellen. Wenn der Header auf eine leere Zeichenfolge festgelegt ist, HttpClient wird stattdessen der Hostname aus der URL verwendet.
Hinweis
Das Anpassen des Hostheaders wirkt sich auf die Überprüfung des Serverzertifikats aus. Standardmäßig erwartet der Client, dass das Serverzertifikat mit dem Hostnamen im Hostheader übereinstimmt.
Manuelle SslStream-Authentifizierung über ConnectCallback
Eine kompliziertere, aber auch leistungsstärkere Option ist die Verwendung der SocketsHttpHandler.ConnectCallback. Seit .NET 7 ist es möglich, eine authentifizierte SslStream zurückzugeben und auf diese Weise anzupassen, wie die TLS-Verbindung hergestellt wird. Innerhalb des Rückrufs können beliebige SslClientAuthenticationOptions Optionen zum Ausführen der clientseitigen Authentifizierung verwendet werden.
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);