Blog

.net: instanziare un web service con certificato scaduto


Richiamare un web service sotto https con certificato scaduto porta l'applicazione a sollevare un eccezione. Vediamo come ignorarla e fruire lo stesso del servizio.
Qualche giorno fa, ho scritto un post, decisamente tecnico, dal titolo ASP: chiamare un web service con un certificato scaduto. In questi giorni ho ricevuto alcune richieste, in cui mi si chiedeva come realizzare la stessa cosa utilizzando .net.

In effetti la domanda è assolutamente lecita, in quanto il modo di procedere in .net è completamente diverso da come si procede in ASP. Questo perché nel vecchio ASP si procede "a mano" andando a lavorare con gli XML dei web services, mentre in .net questo avviene in maniera totalmente trasparente per il programmatore, in quanto è il sistema a occuparsene, creando una classe wrapper, che incapsula l'uso dell'XML. Quindi per il programmatore è tutto più semplice, perché non deve fare altro che richiamare una classe, come fa con tutte le altre del suo programma.

In questo uso, se si richiama un metodo di un web service, che usa un certificato scaduto, viene sollevata una eccezione del tipo WebException con il seguente messaggio di errore:

Connessione sottostante chiusa: Impossibile stabilire una relazione di trust per il canale sicuro SSL/TLS.

Il messaggio in effetti è un po' criptico se non guardiamo bene l'eccezione che è stata sollevata. Ogni eccezione ha una proprietà che si chiama InnerException, nella quale possiamo trovare l'eccezione che ha sollevato l'eccezione corrente. Nella quale possiamo trovare a sua volta un'altra InnerException. In pratica dobbiamo andare a ritrovo nella catena di eccezioni fino a trovare la prima, che a scatenato tutto come una serie di effetti a catena.

Nel nostro caso specifico la prima WebException è sollevata da una eccezione di tipo AuthenticationException che riporta il seguente messaggio di errore:

Il certificato remoto non è stato ritenuto valido dalla procedura di convalida.

Questo è effettivamente molto più descrittivo del precedente, e ci spiega la causa dell'errore.

La soluzione del problema avviene in due passi, che scriverò in Visual Basic.net, ma che possono essere tradotte pari pari in C#.

Il primo passo è di scrivere una funzione di tipo Shared ( o metodo static in C#):

    Private Shared Function CertificateHandler(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal SSLerror As SslPolicyErrors) As Boolean
        Return True
    End Function

Il secondo passo è dopo aver istanziato il web service, prima di richiamare qualunque metodo di aggiungere un gestore di evento. In questo modo:

     Dim ws As New ClasseWebService()
     System.Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf CertificateHandler
     Dim Risultato = ws.MetodoWebService()

Il trucco sta quindi nella proprieta ServerCertificateValidationCallback a cui bisogna associare una funzione di callback che viene richiamata durante la validazione del certificato. La funzione di callback è quella CertificaHandler che vedete al primo passo. Ritornando true, si dice al programma di ignorare gli errori che può rilevare.


Post correlati:

Copyrights © 2011-2024 Tutti i diritti riservati - by Ideativi Srl