6 messaggi dal 23 settembre 2019
Ciao Moreno,
anche se un po' in ritardo...grazie mille per il suggerimento riguardo la Basic Authentication! Ho creato le due classi BasicAuthenticationBehavior e BasicAuthenticationInspector ed ha funzionato alla grande!
Quando dovremo puntare all'amabinte FSE di Sogei di Produzione dovremo usare l'autenticazione tramite certicato CNS, mi hanno detto che basta usare il certificato pubblico contenuto nelle CNS, noi useremo una tessera sanitaria.
In altri client che eseguivano l'autenticazione tramite certificato, nella configurazione del client inserivano delle righe come queste:

<behaviors>
      <endpointBehaviors>
        <behavior name="cltBehavior">
          <clientCredentials supportInteractive="true">
            <clientCertificate findValue="06083270154" x509FindType="FindBySubjectName" storeLocation="LocalMachine" />
            <serviceCertificate>
              <defaultCertificate findValue="wsit-virtasl.rmmg.rsr.rupar.puglia.it"
                  storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
              <authentication certificateValidationMode="PeerTrust" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>


In quei casi però il certificato da usare era fisso, quindi bastava salvarlo nella libreria di Windows (cioè la libreria certificati che si raggiunge anche da Internet Exlorer) e il gioco era fatto.
Ora invece sarà un certificato "dinamico" che cambierà in base all'utente che invoca il client.
Stiamo sviluppando un tool per eseguire la lettura della smart card ed estrarre il certificato pubblico. Questo tool dovrà poi chiamare il mio client passando un po' di info tra cui il Codice Fiscale e il Certificato dell'utente inviante. Secondo te è possibile passare un certificato?
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


Secondo te è possibile passare un certificato?

Sì, ma non te ne fai nulla della sola chiave pubblica.

La richiesta che invierai al webservice Sogei dovrà contenere:
  • La chiave pubblica, che Sogei userà per verificare la firma;
  • La firma del corpo SOAP, che può essere ottenuta usando la chiave privata.


La chiave privata resta al sicuro dentro la smartcard, quindi penso che dovrai usare le API dello smartcard reader per fargli firmare il corpo SOAP. In questo modo non sarà necessario che tu entri in possesso della chiave privata.

Ciao,
Moreno

Enjoy learning and just keep making
6 messaggi dal 23 settembre 2019
Grazie Moreno, provo a seguire il tuo consiglio e vediamo come va.
Intanto grazie!
6 messaggi dal 23 settembre 2019
Ciao Moreno,
sto combattendo con l'autenticazione al Web Service di Sogei tramite CNS, ma ho provato a d usare diverse soluzioni ma con scarsi risultati.
Usando la proxy class generata importando il wsdl come "Service Reference", ho dapprima modificato l'App.config creando un "CustomBinding" che mi permettesse di includere il certificato nella request:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="FseSettings" type="SendCDAtoFSESiciliaClient.FseSettings, SendCDAtoFSESiciliaClient"/>
  </configSections>
  <FseSettings configSource="FseSettings.config" />
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
  </startup>
  <system.serviceModel>
    <bindings>
      <basicHttpsBinding>
        <binding name="comunicazioneMetadatiBinding" messageEncoding="Mtom" />
      </basicHttpsBinding>
      <customBinding>
        <binding name="comunicazioneMetadatiBindingCustom" 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>
    </bindings>
    <client>
      <endpoint address="https://fseservicetest.sanita.finanze.it/FseInsServicesWeb/services/fseComunicazioneMetadati" 
            binding="customBinding" bindingConfiguration="comunicazioneMetadatiBindingCustom"
            contract="FseServiceReference.comunicazioneMetadatiPT" name="fseComunicazioneMetadati" />
    </client>
  </system.serviceModel>
</configuration>




Poi creo il client e la richiesta ed invio al Web Service:
L'invio della richiesta mi genera l'eccezione "System.Security.Cryptography.CryptographicException: 'Keyset non esistente." . Sembra che non nel momento in cui deve firmare la SOAP usando la chiave privata della smart-card, non riesca a leggere la chiave privata della smart-card. Il certificato della smart-card comunque viene però correttamente associato al client. Mi sa che non che non riesc a caricare le API della smart-card (ho installato IDProtect che è quello indicato da Sogei per le CNS-TS), infatti non mi si apre il pop-up di IDProtect in cui mi chiede di inserire il PIN della smart-card.
In altri post come questo:

https://social.msdn.microsoft.com/Forums/it-IT/e69c20cd-2731-46af-860e-58d23b71b5e0/soap-client-mutual-authentication-client-certificate?forum=wcfwfit

ho letto che altri avevano rilevato questo problema di chiave privata non trovata e sembra che avessero abbandonato la strada del WCF con wsdl caricato come "Service Reference" e avessero usato invece l'oggetto "SoapHttpClientProtocol", quindi caricando il wsdl come "Web Reference".

Come secondo tentativo ho provato la strada del "HttpClient", creando una richiesta MTOM completamente a mano.
Nel momento in cui invio la richiesta, mi si apre il pop-up di "IDProtect" dove mi chiede il PIN della smart card, quindi richiama correttamente le API della smart-card. Poi la richiesta viene inviata, ma il Web Service di Sogei mi ritorna l'errore genrico HTTP 500 - "Internal Server Error".
Ho analizzato cosa invio con Fiddler, e la chiamata mi sembra identica a quella che invio usando il WCF (stessi header, stessa struttura dell MTOM, etc). Boh non so più cosa provare.
Pensavo di prendere anch'io la strada del "SoapHttpClientProtocol" anche se non ho molta dimestichezza.
In una rarissima nota della documentazione Sogei riguardante questa integrazione riportano questo:
"NOTE SU ALCUNE TIPOLOGIE DI CLIENT
Per creare un WSclient .NET con autenticazione preventiva si deve usare l&#8217;oggetto SoapHttpClientProtocol sul quale si deve però assolutamente fare un override del metodo GetWebRequest dove viene forzata appunto l&#8217;autenticazione, perché di default non è prevista dalla classe SoapHttpClientProtocol."

Cosa ne pensi?
Modificato da filcat il 10 ottobre 2019 14:39 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao, io l'anno scorso ho combattuto 3 mesi prima di riuscire a inviare una richiesta SOAP corretta a Sogei. Dipende dal fatto che il loro server restituisce un generico errore 500 che non ti aiuta affatto a capire quale sia il problema. Alla fine sono riuscito ad inviare la richiesta ma l'ho dovuta comporre a mano e inviarla con HttpClient. Con WCF proprio non sono riuscito ma è anche vero che ho mollato dopo un po' che non riuscivo a fare progressi.

Nel mio caso ho lavorato con il Portale delle Vendite Pubbliche. Qui trovi un esempio di richiesta SOAP valida, se ti può aiutare.
https://gist.github.com/BrightSoul/4a258725c8a0e3b580ed0ba7cf20c2cc
Guarda giusto il contenuto del tag SOAP-ENV:Header, è lì che vanno inseriti i vari dati:
  • Il BinarySecurityToken è la chiave pubblica
  • Il DigestValue è l'hash sha1 codificato in base64 del Body canonicalizzato
  • Il SignatureValue è la firma codificata in base64 di tutto il nodo SignedInfo canonicalizzato


Più di così non ti so aiutare perché non ho accesso al servizio Sogei che devi usare tu e quindi non posso fare prove.

ciao,
Moreno

Enjoy learning and just keep making
6 messaggi dal 23 settembre 2019
Ciao Moreno,
alla fine pensavo anch'io di continuare sulla strada dell' HttpClient.
Ieri, per cercare dove fosse la causa del problema, ho provato ad inviare a SOAP UI, usando il progetto messo a disposizione da Sogei ed effettivamente SOAP UI mi ritorna questo errore:

"ERROR:com.eviware.soapui.impl.wsdl.mock.DispatchException: Missing operation for soapAction [http://comunicazionemetadati.wsdl.fse.ini.finanze.it/ComunicazioneMetadati] and body element [ComunicazioneMetadatiRichiesta] with SOAP Version [SOAP 1.1]"

Il codice che uso per settare la SOAP Action è questo:

Uri _endpoint = new Uri(_endPointURL);
HttpRequestMessage _requestMessage = new HttpRequestMessage(HttpMethod.Post, _endpoint);

_requestMessage.Headers.Add("SOAPAction", @"http://comunicazionemetadati.wsdl.fse.ini.finanze.it/ComunicazioneMetadati");



a me sembra corretto che dici?
Non è che riesci a condividermi il tuo progetto o almeno la parte in cui costruisci l'Header della SOAP con i vari tag della firma?
6 messaggi dal 23 settembre 2019
Piccola nota: provando col WCF siamo riusciti a creare una richiesta firmata ma il Web Service ci ritorna l'errore "500 - Internal Error".
Ho segnalato la cosa a Sogei e mi hanno risposto che:
"l&#8217;autenticazione con CNS non prevede la firma del messaggio.
Il meccanismo è simile all&#8217;autenticazione con certificato client, la differenza è che non viene utilizzata la chiave privata della carta in quanto non è accessibile.
Per esempi in java si utilizza la classe SSLSocketFactory".
Quindi mi sa che non devo firmare la SOAP...
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


Quindi mi sa che non devo firmare la SOAP...

Se te l'hanno confermato loro sarà senza dubbio così.
Evidentemente non reputano necessario firmare la richiesta SOAP ma gli basta verificare l'identità contenuta nel certificato client.

Questo è diverso dal Portale delle Vendite Pubbliche a cui ho lavorato io, quindi ignora il mio post precedente.

ciao,
Moreno
Modificato da BrightSoul il 16 ottobre 2019 19:05 -

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.