es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Detectar “¿Se requiere un certificado de cliente?” al utilizar C# HttpClient

Mi aplicación de cliente llama a un Azure App Service con HttpClient, algo así:

HttpClientHandler handler = new HttpClientHandler();

if (Detecto que se necesita un certificado)
{
httpClientHandler.ClientCertificates.Add(cert);
httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
}

var client = new HttpClient(handler);
var result = await client.GetAsync(“http://www.contoso.com/”);

Solo quiero agregar el certificado del cliente si puedo detectar que la página lo necesita. Por ejemplo, si pegas una URL en un navegador que requiere certificados de cliente, el navegador ofrece una selección de certificados que el usuario puede elegir. También tengo una lista de certificados en mi aplicación, pero solo quiero mostrarla si el servidor la necesita.

Puedo llamar al servidor y recibir un código de respuesta 403, luego proporcionar mi lista. Sin embargo, puede ser un código de respuesta 403 por otras razones de autenticación, lo que sería confuso.

Supongo que estoy preguntando: “¿Cómo detectan los navegadores que una URL requiere un certificado de cliente?”

Gracias.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para detectar si una URL requiere un certificado de cliente, los navegadores típicamente utilizan el proceso de apretón de manos TLS/SSL. Durante el apretón de manos, el servidor envía una lista de tipos de certificados aceptables al cliente. Si se requiere un certificado de cliente, el servidor incluirá la autoridad de certificación (AC) que emitió el certificado del servidor en esta lista. El navegador luego verificará si tiene algún certificado de cliente almacenado emitido por esa AC y los ofrecerá al usuario para su selección.

    En C# utilizando HttpClient, puedes simular este comportamiento intentando establecer una conexión SSL/TLS con el servidor utilizando HttpClientHandler con la propiedad ClientCertificateOption establecida en Automatic. Si el servidor requiere un certificado de cliente, la conexión fallará y se lanzará una excepción CertificateValidationException. Puedes capturar esta excepción y luego intentar establecer la conexión nuevamente, esta vez con la lista de certificados de cliente conocidos proporcionados en la propiedad HttpClientHandler.ClientCertificates.

    Aquí tienes un ejemplo de código:

    HttpClientHandler handler = new HttpClientHandler();
    try
    {
        // intentar conexión con selección automática de certificado de cliente
        using (var client = new HttpClient(handler))
        {
            var result = await client.GetAsync("https://www.contoso.com/"); 
            // utilizar el resultado si es exitoso
        }
    }
    catch (HttpRequestException ex)
    {
        if (ex.InnerException is CertificateValidationException)
        {
            // el servidor requiere un certificado de cliente, ofrecer lista al usuario
            handler.ClientCertificates.AddRange(GetAvailableCertificates());
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            // intentar conexión nuevamente
            using (var client = new HttpClient(handler))
            {
                var result = await client.GetAsync("https://www.contoso.com/"); 
                // utilizar el resultado si es exitoso
            }
        }
        else
        {
            // manejar la excepción por otras razones
        }
    }
    

    En este ejemplo, si se captura una excepción CertificateValidationException, significa que el servidor requiere un certificado de cliente. Luego llamamos a un método separado GetAvailableCertificates() para recuperar una lista de certificados de cliente que fueron previamente almacenados por el usuario. Esta lista luego puede mostrarse al usuario para su selección. Luego establecemos HttpClientHandler.ClientCertificateOptions en Manual y volvemos a intentar la conexión con el certificado de cliente seleccionado. Si la conexión es exitosa, podemos continuar con otras solicitudes.

Comments are closed.