SOAP Client, Mutual Authentication, client certificate
-
mercoledì 13 giugno 2012 11:33
Hi.
I am developing a soap client for a web service of third part.
The web service require a mutual authentication by client certificate.
I have load the certificate in my client, but they doen't send the certificate to the server for authentication.
This is my app.setting file:
<configSections> <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <section name="ConsolePCT.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/> </sectionGroup> </configSections> <applicationSettings> <ConsolePCT.Properties.Settings> <setting name="ConsolePCT_Test_WSServiziQueryBuilder" serializeAs="String"> <value>https://server.address.com</value> </setting> </ConsolePCT.Properties.Settings> </applicationSettings>this is my soap client code (generate by WSDL):
public partial class WSServiziQueryBuilder : System.Web.Services.Protocols.SoapHttpClientProtocol { public WSServiziQueryBuilder() { this.Url = global::ConsolePCT.Properties.Settings.Default.ConsolePCT_Test_WSServiziQueryBuilder; if ((this.IsLocalFileSystemWebService(this.Url) == true)) { this.UseDefaultCredentials = true; this.useDefaultCredentialsSetExplicitly = false; } else { this.useDefaultCredentialsSetExplicitly = true; } } protected override WebRequest GetWebRequest(Uri uri) { var request = (HttpWebRequest)base.GetWebRequest(uri); if (PreAuthenticate) { NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic"); if (networkCredentials != null) { byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password); request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer); } else { throw new ApplicationException("No network credentials"); } } request.Headers["X-WASP-User"] = XWASPUser.ToLower(); request.KeepAlive = true; request.Method = "POST"; request.Accept = "text/xml"; request.AuthenticationLevel = AuthenticationLevel.MutualAuthRequired; return request; } public string XWASPUser { get; set; } public PCTExecuteHeader Header { get; set; }I have add the GetWebRequest method for insert some additional informations in soap header.
this is my application code:
static void Main(string[] args) { var certifcate = new X509Certificate2(@"C:\CertificatiPCT\Certificate.cer"); var certifcate2 = new X509Certificate2(@"C:\CertificatiPCT\Certificate2.cer"); var header = new PCTExecuteHeader { MustUnderstand = true, Actor = "http://schemas.xmlsoap.org/soap/actor/next", @group = "jpwusers", name = "JPW", role = "JPW" }; var client = new WSServiziQueryBuilder { UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 1.0.3705; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)", SoapVersion = SoapProtocolVersion.Soap11 }; client.ClientCertificates.Add(certifcate); client.ClientCertificates.Add(certifcate2); ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate; var netCredential = new NetworkCredential("jpw", "jpw"); var uri = new Uri(client.Url); var credentials = netCredential.GetCredential(uri, "Basic"); client.Credentials = credentials; client.Header = header; client.PreAuthenticate = true; var retval = client.getServiceNames(); } private static bool RemoteCertificateValidate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors) { return true; }
when i call getServiceNames method i get an http erro : HTTP 401: Authorization Required
if i put a breakpoint in RemoteCertificateValidate method i see that the client certificate is not send to the server.
Can someone help me?
Thank's in advance.
Tutte le risposte
-
mercoledì 13 giugno 2012 12:32
ciao
informativa di servizio: questo è un forum italiano, quindi cortesemente scrivici in italiano ke è meglio per tutti i lettori :)
risposta:
usa WCF (AddServiceReference) in VS al posto di AddWebReference
quando poi userai WCF dovrai configurare il client
questo è un esempio:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <endpoint name="autogenerato" behaviorConfiguration="clientCertificate" address="autogenerato" binding="basicHttpBinding" bindingConfiguration="bindingConfig" contract="autogenerato" /> </client> <bindings> <basicHttpBinding> <binding name="bindingConfig"> <security mode="Transport"> <transport clientCredentialType="Certificate" /> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="clientCertificate"> <clientCredentials> <clientCertificate findValue="NOMEDELTUOCERTIFICATO" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> </configuration>facci sapere quando riesci a usare WCF così vediamo di aiutarti nella sua configurazione lato client
a presto

- Modificato Antonio Esposito mercoledì 13 giugno 2012 12:33
-
mercoledì 13 giugno 2012 14:13
Scusa Antonio ma ero partito da un forum in inglese.. distrazione mia.
Comunque, prima di usare AddWebReference avevo provato a usa AddServiceReference nel progetto di test, ma non funzionava.
Le due utilità di VS non generano lo stesso codice pur partendo entrambe dallo stesso WSDL.
In ogni caso ora sto seguendo le tue indicazioni, ho ricreato il client (ora con ServiceReference) e sto cercando di configurare la connessione come hai indicato tu, pero' ho una eccezione perchè non riesce a trovare il certificato.
Il certificato mi sembra che sia presente (ho verificato che sia nei certificati personali usando certmgr.msc) ma non ha un nome.
Ho provato a utilizzare il numero di serie, che ho individuato all'interno del certificato, ma mi dice "stringa esadecimale non valida".. sotto numero di serie, nelle proprietà del certificato trovo "0e 97 d7", percio' la mia configurazione è diventata:
<clientCredentials> <clientCertificate findValue="0e 97 d7" x509FindType="FindBySerialNumber" storeLocation="LocalMachine" storeName="My"/> </clientCredentials> -
mercoledì 13 giugno 2012 14:26
ciao
per collegare correttamente il certificato 2 cose:
in genere certmgr funziona su CurrentUser (da mettere al posto di LocalMachine)
il thumbprint (l'esadecimale) va messo completo e senza gli spazi. attento se fai copia-incolla ke c'è 1 byte vuoto in più all'inizio
ricorda che il certificato x essere valido deve avere la chiave privata altrimenti non riesci a fare la chiamata
aggiornaci quanto prima
a presto
-
mercoledì 13 giugno 2012 14:46
ok, perfetto, ora il certificato funziona.
Ora pero' sto incontrando un problema che avevo già risolto in precedenza quando avevo utilizzato la WebReference. Il problema è che devo inserire un header nella chiamata al servizio. Avevo risolto in questo modo:
Ho aggiunto una proprietà al client:
public PCTHeader Header { get; set; }
questa è classe PCTHeader:
using System.Web.Services.Protocols; using System.Xml.Serialization; [XmlRoot(ElementName = "InvocationDomain", Namespace = "http://www.netserv.it/anag/security", IsNullable = false)] public class PCTHeader : SoapHeader { [XmlNamespaceDeclarations] public XmlSerializerNamespaces xmlsn { get { var xsn = new XmlSerializerNamespaces(); xsn.Add("ns1", "http://www.netserv.it/anag/security"); return xsn; } set { } } [XmlAttribute] public string group { get; set; } [XmlAttribute] public string name { get; set; } [XmlAttribute] public string role { get; set; } }
e poi nella cahiamata al metodo del client ho aggiunto un attributo:
[SoapHeader("Header")]
ho replicato questa cosa anche nel nuovo cliente WCF, ma l'header che viene generato (lo controllo tramite fiddler) non contiene le nuove informazioni..
-
mercoledì 13 giugno 2012 15:38
[MessageContract(WrapperNamespace="http://ns1.test.com")] public class MyServiceRequest { [MessageHeader(Namespace="http://header.test.com")] public string HeaderProp { get; set; } [MessageBodyMember] public string BodyProp { get; set; } }
ciao
se vuoi gestire gli header, devi alterare il contratto di servizio mettendo come request un MessageContract
poi nel message contract, vai a specificare cosa va in header e cosa in body
-
giovedì 14 giugno 2012 08:23
Ciao, ho sistemato l'invio degli header.
Il messaggio che dovrei ottenere è questo:
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <ns1:InvocationDomain xmlns:ns1="http://www.netserv.it/anag/security" soap:mustUnderstand="1" soap:actor="http://schemas.xmlsoap.org/soap/actor/next" group="jpwusers" name="JPW" role="JPW"/> </soap:Header> <soap:Body> <getServiceNames xmlns="urn:CONS-SICC-BE" /> </soap:Body> </soap:Envelope>
Il messaggio che ottengo invece è questo:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <h:Header s:actor="http://schemas.xmlsoap.org/soap/actor/next" s:mustUnderstand="1" group="jpwusers" name="JPW" role="JPW" xmlns:h="http://www.netserv.it/anag/security" xmlns="http://www.netserv.it/anag/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"x mlns:xsd="http://www.w3.org/2001/XMLSchema"/> </s:Header> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <getServiceNames xmlns="urn:CONS-SICC-BE"/> </s:Body> </s:Envelope>
che è identico a parte gli alias dei namespace e il loro posizionamento nel messaggio, ma questo non dovrebbe essere un problema.
Ora mi manca da aggiustare un'altra parte che avevo già sistemato nella versione precedente in questo modo e che riguarda l'invio di informazioni non nell'header del messaggio, ma della chiamata al servizio. Il risultato dovrebbe essere questo:
Accept-Encoding: gzip,deflate Content-Type: text/xml Authorization: Basic anB3Ompwdw== X-WASP-User: kkkzzzzyyyffff Content-Length: 984 Host: 89.119.251.100:8081 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
in particolare devo inserire il campo Authorization e X-WASP-User. Avevo risolto modificando il client con questo codice:
protected override WebRequest GetWebRequest(Uri uri) { var request = (HttpWebRequest)base.GetWebRequest(uri); if (PreAuthenticate) { NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic"); if (networkCredentials != null) { byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password); request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer); } else { throw new ApplicationException("No network credentials"); } } request.Headers["X-WASP-User"] = XWASPUser.ToLower(); return request; }
Qual'è l'equivalente in WCF?
Grazie in anticipo per l'aiuto..
-
giovedì 14 giugno 2012 09:35
Mi rispondo da solo, per informazione di tutti.
Per inserire header direttamente nella chiamata al servizio, anzichè nel messaggio soap sono sufficienti queste poche righe di codice:
var client = new PCTClient.ServiziQueryBuilderClient(); var prop = new HttpRequestMessageProperty(); byte[] credentialBuffer = new UTF8Encoding().GetBytes("aaa" + ":" + "bbb"); prop.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer); using (new OperationContextScope(client.InnerChannel)) { OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = prop; var serviceNames = client.getServiceNames(); }Questo inserisce l'headers Authorization prima del messaggio soap valorizzato a "Basic YWFhOmJiYg=="..
Ora sono al punto di partenza. Ottengo un errore HTTP 401 dal server e non capisco se il client invia o meno il certificato per la mutua autenticazione..
-
giovedì 14 giugno 2012 09:42
ciao
è ovvio ke nn funziona
o autentichi con X509 o autentichi con basic
io pensavo che volessi aggiungere degli header veri (custom)
non autenticarti manualmente con l'header della basic authentication che WCF supporta automaticamente e non ci sarebbe stato bisogno di scrivere quel codice, ma semplicemente cambiare il config
probabilmente tu non usi davvero la mutua autenticazione x509, ma la mutua autenticazione nel senso che fai login con basic e validi il certificato server a ritroso
ma questo è tutt'altro scenario
questo un config di esempio:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <endpoint name="autogenerato" behaviorConfiguration="clientCertificate" address="autogenerato" binding="basicHttpBinding" bindingConfiguration="bindingConfig" contract="autogenerato" /> </client> <bindings> <basicHttpBinding> <binding name="bindingConfig"> <security mode="Transport"> <transport clientCredentialType="Basic" /> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="clientCertificate"> <clientCredentials> <serviceCertificate> <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" trustedStoreLocation="CurrentUser"/> <!-- validazione automatica in peer o chain trust devi aggiungere il cert server in trusted peoples--> <defaultCertificate findValue="123131231231" x509FindType="FindByThumbprint" storeLocation="CurrentUser" storeName=""/> <!-- autenticazione manuale del cert server, devi avere il cert da qualche parte esplicita e dirgli qual'è --> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>poi per autenticarti lato client:
var client = new ServiceReference1.MyServiceClient(); client.ClientCredentials.UserName.UserName="username"; client.ClientCredentials.UserName.Password = "pwd";considera che il binding basic così impostato usa SSL quindi devi andare in HTTPS
aggiornaci quando puoi
a presto
-
giovedì 14 giugno 2012 13:22
Ciao, a scanso di equivoci ho chiesto chiarimenti via mail al gestore del servizio (Ministero della giustizia....) riguardo le procedure di autenticazione.
Ti riepilogo quello che ho in mano io e che il ministero mi ha fornito:
- Un progetto di esempio che gira su SOAP UI e che utilizza un canale non protetto (http) per interrogare un webservice di test e che utilizza l'autenticazione Basic con nome utente e password per l'autenticazione (se rimuovo nome utente e password il web service non mi autentica: "L'utente NOBODY non può eseguire l'autenticazione")
- Il web service vero e proprio gira su un canale protetto (https) e non esiste un progetto di esempio per tale tipo di canale.......
- So che ogni utente che che si registra al servizio viene munito di certificato da utilizzare per la "mutua autenticazione" (almeno così dice la documentazione che il ministero mi ha fornito), in abbinamento al codice fiscale del soggetto da inserire come header del messaggio con un parametro custom che si chiama X-WASP-User. Io sono in possesso sia di un certificato valido che del corrispondente codice fiscale.
E' presumibile che il certificato sostituisca le credenziali username e password, ma non ho trovato nessuna conferma su questo punto nella documentazione.
Ho mandato una richiesta di delucidazioni al supporto tecnico del Ministero. ora sono in attesa..
Nel frattempo ho fatto alcune prove. Se non inserisco il codice che ho postato sopra, ma utilizzo semplicemente la configurazione con autenticazione basic e imposto le ClientCredentials, ho notato che l'informazione sull'autenticazione nel messaggio inviato al server non è presente. Manca proprio l'header Authorization.. con il codice che ho postato invece viene inserito.
Poi ho provato a usare il certificato di cui sono in possesso con quest configurazione:
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="ServiziQueryBuilderSOAPBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="Transport"> <transport clientCredentialType="Certificate" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="clientCertificate" > <clientCredentials> <clientCertificate findValue="0e97d7" x509FindType="FindBySerialNumber" storeLocation="CurrentUser" storeName="My"/> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <client> <endpoint address="https://ext.processotelematico.giustizia.it/pda/pycons/GLMI/JPW_SICID" binding="basicHttpBinding" bindingConfiguration="ServiziQueryBuilderSOAPBinding" contract="PCTClient.ServiziQueryBuilder" behaviorConfiguration="clientCertificate" name="ServiziQueryBuilderSOAPPort" /> </client> </system.serviceModel> </configuration>Parte della configurazione è stata generata durante la creazione del client partendo dal WSDL, parte è stata modificata secondo le tue indicazioni precedenti
In questo caso la risposta del server è questa:"La richiesta HTTP non è autorizzata con lo schema di autenticazione client 'Anonymous'. Intestazione di autenticazione ricevuta dal server: ''
Ho l'impressione che il server non riceva il certificato dal client..
-
giovedì 14 giugno 2012 15:51
da quello che mi dici, confido nel fatto che tu voglia usare la Basic authentication, più l'autenticazione del certificato server per la mutua autenticazione
la configurazione corretta dovrebbe essere da config con la Transport in Basic, che va da sola in https e mette nell'header HTTP_AUTHORIZATION
il certificato è per autenticare il server non il client
dovresti avere tutto il necessario nel mio precedente post
impostare le client credentials senza la giusta configurazione nel .config non serve perchè non vengono serializzate le informazioni di sicurezza
facci sapere
a presto
-
giovedì 14 giugno 2012 15:59
-
venerdì 15 giugno 2012 10:07
Ciao Antonio,
ti riporto quello che la documentazione che mi è stata fornita dal ministero dice in merito all'autenticazione:
"Il protocollo https è inteso in mutua autenticazione e quindi il chiamante deve presentare il certificato di un utente censito sul ReGIndE. Il certificato deve essere rilasciato da una CA accreditata da DigitPA"
Quello che mi viene da pensare è che la Basic Authentication sia stata usata solo per l'ambiente di prova, mentre per l'ambiente reale venga sostituita dal certificato che l'utente possiede..
Io il certificato valido ce l'ho, ma se provo a usare l'utenticazione che ti ho postato sopra e ce ti riporto qui per semplicità:
<security mode="Transport"> <transport clientCredentialType="Certificate" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security>Ottengo in risposta dal server "La richiesta HTTP non è autorizzata con lo schema di autenticazione client "Anonymous" ecc. ecc. che ti ho postato sopra.
Sicuramente mi sbaglierò, ma leggendo la risposta mi sembra che il server non riceva il certificato e quindi non sia in grado di capire chi sta facendo la richiesta.
C'è un modo per vedere se il client invia o meno il certificato al server?
PS. Resto sempre in attesa di una risposta di conferma alla mia ipotesi dal ministero.. spero rispondano al più presto.
-
venerdì 15 giugno 2012 10:21
ciao
ricapitoliamo: quindi la Basic non esiste!
usi il certificato per l'autenticazione client (quindi di mutuo non c'è niente a meno che tu non stia rivalidando il certificato del server)
l'anonymous avviene quando non vai direttamente in modalità autenticata, ma inizi la comunicazione appunto anonimamente
se hai configurato correttamente il tutto, non dovesti avere questo problema
puoi postare tutto il .config del client??
grazie
-
venerdì 15 giugno 2012 10:26
Ciao,
si, la basic non esiste, da quello che ho capito (aspetto conferma formale via mail)
Questo è il config lato client:
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="ServiziQueryBuilderSOAPBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="Transport"> <transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" /> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="clientCertificate" > <clientCredentials > <clientCertificate findValue="0e97d7" x509FindType="FindBySerialNumber" storeLocation="CurrentUser" storeName="My" /> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <client> <endpoint address="https://ext.processotelematico.giustizia.it/pda/pycons/GLMI/JPW_SICID" behaviorConfiguration="clientCertificate" binding="basicHttpBinding" bindingConfiguration="ServiziQueryBuilderSOAPBinding" contract="PCTClient.ServiziQueryBuilder" name="ServiziQueryBuilderSOAPPort" /> </client> </system.serviceModel> </configuration>Grazie per l'aiuto e la pazienza..
-
venerdì 15 giugno 2012 10:32
prova ad usare il wsHttpBinding o il ws2007HttpBinding che il problema è nell'implementazione della chiamata
a credere ad apache il basic inizia la comunicazione in anonymous.....
se non riesci così, dovrai configurare un custom-binding
a presto
-
venerdì 15 giugno 2012 13:10
Ciao,
ho provato a configurare un custom-binding minimale in questo modo:
<customBinding> <binding name="ServiziQueryBuilderSOAPBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"> <transactionFlow /> <security authenticationMode="CertificateOverTransport"/> <textMessageEncoding messageVersion="Soap11" /> <httpsTransport requireClientCertificate="True" /> </binding> </customBinding>ma ottengo questa eccezione appena tento di chiamare il metodo sul servizio: "Chiave privata non presente nel certificato X.509."
e in effetti la chiave privata non è presente nel certificato.
E' indispensabile che la chiave privata sia presente nel certificato?
Perchè prima di usare un custom-binding questo problema non si è presentato?
Grazie...
-
mercoledì 27 giugno 2012 16:12
Salve, Michele
sto affrontando un problema del tutto simile. Volevo chiederti se nel frattempo hai risolto e in che modo.
Grazie :)
-
venerdì 29 giugno 2012 13:56
Ciao,
al momento non ho ancora risolto del tutto..
o meglio, ho risolto il problema del certificato.. funziona solo se è presente la smartcard/chiavetta usb che contiene i certificati.
Cmq ho dovuto abbandonare WCF e sono passato a un proxy che estende la classe SoapHttpClientProtocol.
Ora l'autenticazione funziona, pero' ho un errore strano HTTP 503: Proxy error, bad gateway che non risesco a risolvere.
La cosa strana è che ho inviato il messaggio soap al supporto tecnico del gestore del servizio e mi ha detto che loro l'hanno provata e funziona.
A questo punto credo che il problema dipenda dagli header che il client invia prima di spedire il messaggio vero e proprio, solo che fino ad oggi non ho trovato un modo per manipolarli come vorrei..
-
sabato 28 luglio 2012 13:43
Ciao,
La "Mutual SSL autentication" richiede che il client esponga un certificato (x509) con chiave privata: http://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication
Il Ministero della Giustizia ha adottato questo tipo di autenticazione per l'accesso al Processo Telmatico: http://www.processotelematico.giustizia.it/pdapublic/
Io sto progettando un software per l'accesso a tale "web service" ma la maggior parte dei miei utenti (Avvocati) possiede una smart card che (per motivi di sicurezza) NON CONSENTE l'esportazione della chave privata. Per tale motivo non posso esportare il certificato in formato PKCS #12 (.pfx).
Ho provato ad autenticarmi utilizzando un certificato in formato .cer ed in formato PKCS #7 (vedi codice c#), ma il server mi ha restituito il seguente messaggio di errore: "502 Proxy Error The proxy server received an invalid response from an upstream server The proxy server could not handle the request Error reading from remote server Apache/2.2.3 (Red Hat) Server at Port 443".
Qualcuno potrebbe, gentilmente, dirmi:
1. Se esiste un modo per effettuare la "Mutual authentication" lato client senza esporre la chiave privata.
2. Se esiste un modo per recuperare (dalla Smart Card) la chiave privata NON ESPORTABILE e con essa creare un clone del certificato in formato .pfx
3. Se è possibile effettuare la "Mutual authentication" lato client in qualche altro modo?
Sono graditi frammenti di codice in C#
Grazie :-)
Lello Passannanti
**********************************************
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static HttpWebRequest CreateWebRequest(string url)
{
Uri uri = new Uri(url);HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Headers.Add("SOAP:Action");
webRequest.Headers.Add("X-WASP-User", "psssrl52s19h703u");
webRequest.KeepAlive = true;
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
webRequest.AuthenticationLevel = AuthenticationLevel.MutualAuthRequired;
webRequest.ClientCertificates.Add(certificate);
return webRequest;}
- Modificato Juris Quick sabato 28 luglio 2012 13:47 x
- Modificato Juris Quick sabato 28 luglio 2012 13:51 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 13:52 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 13:53 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 13:54 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 13:55 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 13:58 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 14:16 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 14:17 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 14:24 ortografia
- Proposto come risposta Juris Quick sabato 28 luglio 2012 16:54
- Proposta come risposta annullata Juris Quick sabato 28 luglio 2012 16:54
- Modificato Juris Quick sabato 28 luglio 2012 16:56 ortografia
- Modificato Juris Quick sabato 28 luglio 2012 17:06
- Modificato Juris Quick sabato 28 luglio 2012 18:11
- Modificato Juris Quick sabato 28 luglio 2012 18:26
- Modificato Juris Quick domenica 29 luglio 2012 22:31
- Modificato Juris Quick domenica 29 luglio 2012 22:34
- Modificato Juris Quick domenica 29 luglio 2012 22:36
- Modificato Juris Quick domenica 29 luglio 2012 22:38
- Modificato Juris Quick domenica 29 luglio 2012 22:38
- Modificato Juris Quick domenica 29 luglio 2012 22:40
- Modificato Juris Quick domenica 29 luglio 2012 22:45
- Modificato Juris Quick domenica 29 luglio 2012 22:46
- Modificato Juris Quick lunedì 30 luglio 2012 05:32
- Modificato Juris Quick lunedì 30 luglio 2012 05:33
- Modificato Juris Quick lunedì 30 luglio 2012 05:34
- Modificato Juris Quick martedì 31 luglio 2012 05:27
-
martedì 14 agosto 2012 09:25
PROBLEMA RISOLTO:
L'errore: 502 (bad gateway) non dipendeva dai certificati ma dal fatto che, per la trasmissione dei dati, il proxy del Ministero della Giustiza utilizza il protocollo HTTP 1.0 mentre il mio applicativo utilizzava il protocollo HTTP 1.1.
Per correggere l'errore 502 (bad gateway) è bastato aggiungere, nella chiamata al servizio, la seguente istruzione (vedi codice). Ora riesco a connettermi correttamente. Spero che questo "post" possa essere utile ad altri.
Cordiali saluti
Lello Passannanti
=====================================================
public static HttpWebRequest CreateWebRequest(string url)
{
Uri uri = new Uri(url);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);//Questa istruzione corregge l'errore 502 (Bad gateway)
webRequest.ProtocolVersion = HttpVersion.Version10;
webRequest.Proxy = null;
webRequest.Headers.Add("SOAP:Action");
webRequest.KeepAlive = true;
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
webRequest.AuthenticationLevel = AuthenticationLevel.MutualAuthRequired;
if (certificate != null)
{
webRequest.ClientCertificates.Add(certificate);
}return webRequest;
}
- Modificato Juris Quick martedì 14 agosto 2012 09:28
-
giovedì 27 dicembre 2012 21:28
Ciao,
sto implementando per alcuni clienti il collegamento PCT, volevo chiederti se hai poi risolto i tuoi problemi e se eventualmente hai a disposizione una libreria o del codice (anche a pagamento) per il collegamento.
Se ti interessa puoi contattarmi a chiccof@libero.it
Grazie

