WCF Sicurezza con Doppio Certificato
Vediamo un po’ come configurare un servizio WCF (Web Service) con sicurezza a livello di messagio: solo il cotenuto dell’envelope soap sarà cifrato. Con questo sistema varrà garantita oltre alla sicurezza anche l’autenticità di client e server: il client avendo a disposizione il certificato pubblico del server potrà verificarne l’autenticità oltre ad utilizzarlo per cifrare i messaggi verso il servizio. In modo duale anche il servizio potrà controllare autenticità del client e cifrare il conenuto a lui destinato.
Tralasciamo la creazione del servizio e veniamo subito alla configurazione….
Creazione dei Certificati
Iniziamo con la generazione dei certificati che ci serviranno per cifrare il contenuto dei messaggi e autenticare client e server. Per la generazione utilizziamo l’utility da linea di comando disponibile con visual studio makecert per la generazione del certificato e chiave private e pvk2pfx per l’esportazione in formato pfx (in cui è possibile esportare anche la chiave privata per il deploy). Tali utility a linea di comando sono disponibili utilizzando il prompt dei comandi di visual studio (che ha già il path correttamente configurato).
Generazione Certificato Server
makecert.exe -n "CN=Service" -sky exchange -sv Service.pvk Service.cer
pvk2pfx.exe -pvk Service.pvk -spc Service.cer
Generazione Certificato Client
makecert.exe -n "CN=Client" -sky exchange -sv Client.pvk Client.cer
pvk2pfx.exe -pvk Client.pvk -spc Client.cer
Configurazione dei Servizi
Generati i certificato procediamo con la configurazione del nostro servizio WCF e del client in modo da utilizzare i certificati per autenticare mutuamente client e server e cifrare i messaggi.
Configurazione del Servizio
<system.serviceModel> <services> <service name="ServiceName" behaviorConfiguration="CustomServiceBehaviour"> <endpoint address="" binding="wsHttpBinding" bindingConfiguration="CustomBinding" contract="MyNamespace.IServiceContract"> <identity> <certificateReference storeName="My" storeLocation="CurrentUser" x509FindType="FindBySubjectName" findValue="Service" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <bindings> <wsHttpBinding> <binding name="CustomBinding"> <security mode ="Message"> <message clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="CustomBehaviour"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="False" /> <serviceCredentials> <serviceCertificate findValue="AuthService" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" /> <clientCertificate> <authentication certificateValidationMode="PeerOrChainTrust" /> </clientCertificate> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
Configurazione Del Client
<system.serviceModel> <client> <endpoint address="http://address/MyService.svc" behaviorConfiguration="CustomBehaviour" binding="wsHttpBinding" bindingConfiguration="ClientBinding" contract="AdhocWs.IAdhocServices" name=""> <identity> <certificateReference storeName="TrustedPeople" storeLocation="CurrentUser" x509FindType="FindBySubjectName" findValue="AdhocBridgeService" /> </identity> </endpoint> </client> <bindings> <wsHttpBinding> <binding name="ClientBinding"> <security mode="Message" > <message clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="CustomBehaviour"> <dataContractSerializer maxItemsInObjectGraph="2147483646" /> <clientCredentials> <clientCertificate findValue="Client" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" /> <serviceCertificate> <authentication certificateValidationMode="PeerOrChainTrust" /> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
Con questa configurazione i certificati dovranno trovarsi nel Certificate Store dell’utente che esegue l’applicazione in particolare il Client deve avere il certificato Client con chiave privata e il certificato del server senza chiave privata. L’utente che esegue il Servizio dovrà avere il certificato Service con chiave privata e il certificato client senza privata. I certificati con chiave privata dovranno trovarsi in Personal mentre i certificati senza chiave privata in Trusted People.
Configurazione con IIS
Nel caso in cui il server, ma anche il client, siano ospitati da IIS l’application Pool dovrà essere configurato in modo da utilizzare un utente con i corretti certificati nel relativo Certificate Store.
Attenzione! Affinche il certificate store sia caricato e accessibile per l’utente dovrà essere caricato il profilo dell’utente.