WCF ja sertifikaadiga autentimine
04.06.2008 | Siim
Hiljuti tekkis vajadus kasutada .NETi rakenduses PHP veebiteenust. Kuna rakenduses oli kasutuses juba Windows Communication Foundation, otsustasin ka seekord seda kasutada. Kasutades Svcutil.exe (või Visual Studio 2008) abi oli teenuse proxy klassi genereerimine lihtne ja sujus valutult. Olgu öeldud ka, et PHP teenus oli täitsa eeskujulikult kirjutatud
Suhtlus toimus üle SSL kanali ja autentimiseks kasutati sertifikaate. Selleks on vaja, et kliendi rakenduses oleks installitud serveri sertifikaat (ja vajaduse korral ka lisa CA’d, kui neid ei ole) ning vajalik on ka kliendi enda sertifikaat koos privaatse võtmega. Kliendi sertifikaat väljastatakse teenuse pakkuja poolt.
Kuidas kõik tööle saada?
Sertifikaadid tuleks installida Windowsi Certificate Store’i asukohaga LocalMachine. Mis teeb need kõigile domeeni kasutajatele kättesaadavaks, kellel on ligipääs antud sertifikaatidele. Kliendi sertifikaadi installisin LocalMachine/Personal‘i alla. Mis on ka vaikimisi kohaks privaatvõtmetega sertifikaatide installimiseks. Infot selle kohta, millist sertifikaati kasutada ja kuhu täpsemalt installida, annab infot MSDN.
Järgmiseks tuleb WCF kliendile öelda, et kasutatakse SSLi ja sertifikaate. Selleks binding‘ute alla lisada vastav blokk:
<basicHttpBinding> <binding name="SecureBinding"> <security mode="Transport"> <transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" /> </security> </binding> </basicHttpBinding>
Samuti tuleb kätte näidata sertifikaat, mida kasutama hakatakse. Selleks tuleb lisada vastav <behavior> blokk. Täpsemalt saab atribuutide väärtustest lugeda MSDNist.
<behaviors> <endpointBehaviors> <behavior name="ClientAuthBehavior"> <clientCredentials> <clientCertificate findValue="ClientCert" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" /> </clientCredentials> </behavior> </endpointBehaviors> </behaviors>
Kliendi poolelt peaks kõik põhiline olemas olema, et asi tööle saada. Testimiseks kasutasin konsooli rakendust ning sellega töötas ilusti. Aga kui ma üritasin sama asja käivitada Windowsi teenuse kaudu, siis sain veateate, et turvalist ühendust ei õnnestunud luua. Mõne aja pärast tuli ka põhjus välja. Nimelt domeeni kasutajal, mille alt Windowsi teenus töötas, puudusid vastavad õigused kliendi sertifikaadi privaatvõtme lugemiseks. Sest vaikimisi saavad privaatvõtmeid lugeda ainult administraatorid ja kasutaja SYSTEM.
Kõigepealt tuli selleks failisüsteemis üles otsida koht, kuhu on salvestatud vastav privaatvõti. Vaikimisi peaks selleks olema kataloog C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\. Mina kasutasin selleks FindPrivateKey.exe utiliidi abi, mis tuleb kaasa WCFi näidete pakiga. Leiab selle koos lähtekoodiga siit. Kasutamine näeb välja nii:
FindPrivateKey.exe My LocalMachine -n "CN=ClientCert"
Esimene parameeter näitab lao nime, teine asukohta ja kolmas on sertifikaadi Subject name. Kolmanda parameetri asemel võib kasutada ka võtit -t, millega tuleb kaasa anda sertifikaadi sõrmejälg (thumbprint). Tulemuseks on kataloogi ja faili nimi, kus privaatvõti asub. Seega Windowsi teenuse kasutajale tuleb sellele võtmele lugemisõigus anda. Seda saab teha, kas kasutades utiliiti cacls.exe või otse failisüsteemi kaudu. Cacls.exe kasutamine näeb välja nii:
cacls.exe "path\to\private\key" /E /G "DOMEEN\KASUTAJA":R
Sellega on Windowsi teenuse kasutajale antud õigus lugeda vajalikku private keyd ning SSLi ühenduse loomine õnnestub nüüd ka Windowsi teenuse vahendusel. Täpsemalt võib lugeda Codeplexi How-To’st.
