Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Quando um cliente e um servidor negociam uma conexão HTTPS, uma conexão TLS precisa ser estabelecida primeiro. Como parte do handshake do TLS, o cliente envia o nome de domínio do servidor ao qual está se conectando em uma das extensões do TLS. Quando vários servidores (virtuais) são hospedados no mesmo computador, esse recurso do protocolo TLS permite que os clientes distinguem a qual desses servidores eles estão se conectando e defina as configurações do TLS, como o certificado do servidor, adequadamente.
Quando uma solicitação HTTP usando HttpClient é feita, a implementação seleciona automaticamente um valor para a extensão SNI (indicação de nome do servidor) com base na URL à qual o cliente está se conectando. Para cenários que exigem mais controle manual da extensão, você pode usar uma das abordagens a seguir.
Cabeçalho do host
O cabeçalho HTTP do host executa uma função semelhante à da extensão SNI no TLS. Ele permite que o servidor de destino distingue entre as solicitações de vários nomes de host em um único endereço IP.
HttpClient preenche automaticamente o cabeçalho host usando o URI da solicitação. No entanto, você também pode definir seu valor manualmente e HttpClient também usará o novo valor na extensão SNI. Você pode usar ou HttpRequestMessage.Headers.Host ou HttpClient.DefaultRequestHeaders.Host para obter esse efeito.
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);
Observação
Esse método não permite que você evite enviar SNI completamente ao se conectar a uma URL com um nome de host. Se o cabeçalho estiver definido como cadeia de caracteres vazia, HttpClient usará o nome do host da URL.
Observação
A personalização do cabeçalho host afeta a validação do certificado do servidor. Por padrão, o cliente espera que o certificado do servidor corresponda ao nome do host no cabeçalho host.
Autenticação manual do SslStream por meio do ConnectCallback
Uma opção mais complicada, mas também mais poderosa, é usar o SocketsHttpHandler.ConnectCallback. Desde o .NET 7, é possível retornar um autenticado SslStream e, portanto, personalizar como a conexão TLS é estabelecida. Dentro do callback, opções arbitrárias SslClientAuthenticationOptions podem ser usadas para realizar a autenticação no cliente.
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);