Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Sampel ini menunjukkan cara menerapkan Validator Sertifikat X.509 kustom. Ini berguna dalam kasus di mana tidak ada mode Validasi Sertifikat X.509 bawaan yang sesuai untuk persyaratan aplikasi. Sampel ini memperlihatkan layanan yang memiliki validator kustom yang menerima sertifikat yang diterbitkan sendiri. Klien menggunakan sertifikat seperti itu untuk mengautentikasi ke layanan.
Catatan: Karena siapa pun dapat membuat sertifikat yang dikeluarkan sendiri, validator kustom yang digunakan oleh layanan kurang aman daripada perilaku default yang disediakan oleh ChainTrust X509CertificateValidationMode. Implikasi keamanan dari ini harus dipertimbangkan dengan cermat sebelum menggunakan logika validasi ini dalam kode produksi.
Singkatnya, sampel ini menunjukkan cara:
Klien dapat diautentikasi menggunakan sertifikat X.509.
Server memvalidasi kredensial klien terhadap X509CertificateValidator kustom.
Server diautentikasi menggunakan sertifikat X.509 server.
Layanan ini mengekspos satu titik akhir untuk berkomunikasi dengan layanan, yang ditentukan menggunakan file konfigurasi App.config. Titik akhir terdiri dari alamat, pengikatan, dan kontrak. Pengikatan dikonfigurasi dengan standar wsHttpBinding yang secara default menggunakan WSSecurity dan autentikasi sertifikat klien. Perilaku layanan menentukan mode Kustom untuk memvalidasi sertifikat X.509 klien bersama dengan jenis kelas validator. Perilaku ini juga menentukan sertifikat server menggunakan elemen serviceCertificate. Sertifikat server harus berisi nilai yang sama untuk SubjectName sebagai dalam findValue<serviceCertificate>.
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<!-- use host/baseAddresses to configure base address -->
<!-- provided by host -->
<host>
<baseAddresses>
<add baseAddress =
"http://localhost:8001/servicemodelsamples/service" />
</baseAddresses>
</host>
<!-- use base address specified above, provide one endpoint -->
<endpoint address="certificate"
binding="wsHttpBinding"
bindingConfiguration="Binding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
</services>
<bindings>
<wsHttpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults ="true"/>
<serviceCredentials>
<!-- The serviceCredentials behavior allows one -->
<!-- to specify authentication constraints on -->
<!-- client certificates. -->
<clientCertificate>
<!-- Setting the certificateValidationMode to -->
<!-- Custom means that if the custom -->
<!-- X509CertificateValidator does NOT throw -->
<!-- an exception, then the provided certificate -->
<!-- will be trusted without performing any -->
<!-- validation beyond that performed by the custom -->
<!-- validator. The security implications of this -->
<!-- setting should be carefully considered before -->
<!-- using Custom in production code. -->
<authentication
certificateValidationMode="Custom"
customCertificateValidatorType =
"Microsoft.ServiceModel.Samples.CustomX509CertificateValidator, service" />
</clientCertificate>
<!-- The serviceCredentials behavior allows one to -->
<!-- define a service certificate. -->
<!-- A service certificate is used by a client to -->
<!-- authenticate the service and provide message -->
<!-- protection. This configuration references the -->
<!-- "localhost" certificate installed during the setup -->
<!-- instructions. -->
<serviceCertificate findValue="localhost"
storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Konfigurasi titik akhir klien terdiri dari nama konfigurasi, alamat absolut untuk titik akhir layanan, pengikatan, dan kontrak. Pengikatan klien dikonfigurasi dengan mode dan pesan clientCredentialTypeyang sesuai.
<system.serviceModel>
<client>
<!-- X509 certificate based endpoint -->
<endpoint name="Certificate"
address=
"http://localhost:8001/servicemodelsamples/service/certificate"
binding="wsHttpBinding"
bindingConfiguration="Binding"
behaviorConfiguration="ClientCertificateBehavior"
contract="Microsoft.ServiceModel.Samples.ICalculator">
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<serviceCertificate>
<!-- Setting the certificateValidationMode to -->
<!-- PeerOrChainTrust means that if the certificate -->
<!-- is in the user's Trusted People store, then it -->
<!-- is trusted without performing a validation of -->
<!-- the certificate's issuer chain. -->
<!-- This setting is used here for convenience so -->
<!-- that the sample can be run without having to -->
<!-- have certificates issued by a certification -->
<!-- authority (CA). This setting is less secure -->
<!-- than the default, ChainTrust. The security -->
<!-- implications of this setting should be -->
<!-- carefully considered before using -->
<!-- PeerOrChainTrust in production code.-->
<authentication
certificateValidationMode="PeerOrChainTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Implementasi klien menetapkan sertifikat klien yang akan digunakan.
// Create a client with Certificate endpoint configuration
CalculatorClient client = new CalculatorClient("Certificate");
try
{
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "test1");
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
// Call the Multiply service operation.
value1 = 9.00D;
value2 = 81.25D;
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Call the Divide service operation.
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
client.Close();
}
catch (TimeoutException e)
{
Console.WriteLine("Call timed out : {0}", e.Message);
client.Abort();
}
catch (CommunicationException e)
{
Console.WriteLine("Call failed : {0}", e.Message);
client.Abort();
}
catch (Exception e)
{
Console.WriteLine("Call failed : {0}", e.Message);
client.Abort();
}
Sampel ini menggunakan X509CertificateValidator kustom untuk memvalidasi sertifikat. Sampel mengimplementasikan CustomX509CertificateValidator, berasal dari X509CertificateValidator. Lihat dokumentasi tentang X509CertificateValidator untuk informasi selengkapnya. Sampel validator kustom khusus ini mengimplementasikan metode Validasi untuk menerima sertifikat X.509 apa pun yang diterbitkan sendiri seperti yang ditunjukkan dalam kode berikut.
public class CustomX509CertificateValidator : X509CertificateValidator
{
public override void Validate ( X509Certificate2 certificate )
{
// Only accept self-issued certificates
if (certificate.Subject != certificate.Issuer)
throw new Exception("Certificate is not self-issued");
}
}
Setelah validator diterapkan dalam kode layanan, host layanan harus diberi tahu tentang instans validator yang akan digunakan. Ini dilakukan menggunakan kode berikut.
serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new CustomX509CertificateValidator();
Atau Anda dapat melakukan hal yang sama dalam konfigurasi sebagai berikut.
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
...
<serviceCredentials>
<!--The serviceCredentials behavior allows one to specify -->
<!--authentication constraints on client certificates.-->
<clientCertificate>
<!-- Setting the certificateValidationMode to Custom means -->
<!--that if the custom X509CertificateValidator does NOT -->
<!--throw an exception, then the provided certificate will -->
<!--be trusted without performing any validation beyond that -->
<!--performed by the custom validator. The security -->
<!--implications of this setting should be carefully -->
<!--considered before using Custom in production code. -->
<authentication certificateValidationMode="Custom"
customCertificateValidatorType =
"Microsoft.ServiceModel.Samples. CustomX509CertificateValidator, service" />
</clientCertificate>
</serviceCredentials>
...
</behavior>
</serviceBehaviors>
</behaviors>
Saat Anda menjalankan sampel, permintaan dan respons operasi ditampilkan di jendela konsol klien. Klien harus berhasil memanggil semua metode. Tekan ENTER di jendela klien untuk mematikan klien.
Menyiapkan File Batch
File batch Setup.bat yang disertakan dengan sampel ini memungkinkan Anda mengonfigurasi server dengan sertifikat yang relevan untuk menjalankan aplikasi yang dihost sendiri yang memerlukan keamanan berbasis sertifikat server. File batch ini harus dimodifikasi agar berfungsi di berbagai komputer atau tanpa host.
Berikut ini memberikan gambaran singkat tentang berbagai bagian file batch sehingga dapat dimodifikasi untuk dijalankan dalam konfigurasi yang sesuai:
Membuat sertifikat server:
Baris berikut dari file batch Setup.bat membuat sertifikat server yang akan digunakan. Variabel %SERVER_NAME% menentukan nama server. Ubah variabel ini untuk menentukan nama server Anda sendiri. Nilai defaultnya adalah localhost.
echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -peMenginstal sertifikat server ke penyimpanan sertifikat tepercaya klien:
Baris-baris berikut dalam file batch Setup.bat menyalin sertifikat server ke penyimpanan tepercaya klien. Langkah ini diperlukan karena sertifikat yang dihasilkan oleh Makecert.exe tidak dipercaya secara implisit oleh sistem klien. Jika Anda sudah memiliki sertifikat yang berakar pada sertifikat akar tepercaya klien—misalnya, sertifikat yang dikeluarkan Microsoft—langkah mengisi penyimpanan sertifikat klien dengan sertifikat server tidak diperlukan.
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeopleMembuat sertifikat klien:
Baris berikut dari file batch Setup.bat membuat sertifikat klien yang akan digunakan. Variabel %USER_NAME% menentukan nama klien. Nilai ini diatur ke "test1" karena ini adalah nama yang dicari kode klien. Jika Anda mengubah nilai %USER_NAME% Anda harus mengubah nilai yang sesuai dalam file sumber Client.cs dan membangun kembali klien.
Sertifikat disimpan di penyimpanan Saya (Pribadi) di bawah lokasi penyimpanan CurrentUser.
echo ************ echo Client cert setup starting echo %USER_NAME% echo ************ echo making client cert echo ************ makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%USER_NAME% -sky exchange -peMenginstal sertifikat klien ke penyimpanan sertifikat tepercaya server:
Baris berikut dalam file batch Setup.bat menyalin sertifikat klien ke penyimpanan orang tepercaya. Langkah ini diperlukan karena sertifikat yang dihasilkan oleh Makecert.exe tidak dipercaya secara implisit oleh sistem server. Jika Anda sudah memiliki sertifikat yang berakar pada sertifikat akar tepercaya—misalnya, sertifikat yang dikeluarkan Microsoft—langkah mengisi penyimpanan sertifikat server dengan sertifikat klien tidak diperlukan.
certmgr.exe -add -r CurrentUser -s My -c -n %USER_NAME% -r LocalMachine -s TrustedPeople
Untuk menyiapkan dan membangun sampel
Untuk membangun solusi, ikuti instruksi dalam Membangun Sampel Windows Communication Foundation.
Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, gunakan instruksi berikut.
Untuk menjalankan sampel pada komputer yang sama
Jalankan Setup.bat dari folder instalasi sampel di dalam perintah Visual Studio yang dibuka dengan hak istimewa administrator. Ini menginstal semua sertifikat yang diperlukan untuk menjalankan sampel.
Penting
File batch Setup.bat dirancang untuk dijalankan dari Visual Studio Command Prompt. Variabel lingkungan PATH yang diatur dalam Prompt Perintah Visual Studio menunjuk ke direktori yang berisi executable yang diperlukan oleh skrip Setup.bat.
Luncurkan Service.exe dari service\bin.
Luncurkan Client.exe dari \client\bin. Aktivitas klien ditampilkan pada aplikasi konsol klien.
Jika klien dan layanan tidak dapat berkomunikasi, lihat Tips Pemecahan Masalah untuk Sampel WCF.
Untuk menjalankan contoh program di berbagai komputer
Buat direktori pada komputer layanan.
Salin file program layanan dari \service\bin ke direktori virtual pada komputer layanan. Salin juga file Setup.bat, Cleanup.bat, GetComputerName.vbs dan ImportClientCert.bat ke komputer layanan.
Buat direktori di komputer klien untuk biner klien.
Salin file program klien ke direktori klien di komputer klien. Salin juga file Setup.bat, Cleanup.bat, dan ImportServiceCert.bat ke klien.
Di server, jalankan
setup.bat servicedi Prompt Perintah Pengembang untuk Visual Studio yang dibuka dengan hak istimewa administrator. Menjalankansetup.batdengan argumenservicemembuat sertifikat layanan dengan nama domain komputer yang sepenuhnya memenuhi syarat dan mengekspor sertifikat layanan ke file bernama Service.cer.Edit Service.exe.config untuk mencerminkan nama sertifikat baru (dalam
findValueatribut di <serviceCertificate>) yang sama dengan nama domain komputer yang sepenuhnya memenuhi syarat. Ubah juga nama komputer dalam <elemen service>/<baseAddresses> dari localhost menjadi nama komputer layanan Anda yang sepenuhnya memenuhi syarat.Salin file Service.cer dari direktori layanan ke direktori klien di komputer klien.
Pada klien, jalankan
setup.bat clientdi Prompt Perintah Pengembang untuk Visual Studio yang dibuka dengan hak istimewa administrator. Menjalankansetup.batdengan argumenclientmembuat sertifikat klien bernama client.com dan mengekspor sertifikat klien ke file bernama Client.cer.Dalam file Client.exe.config di komputer klien, ubah nilai alamat titik akhir agar sesuai dengan alamat baru layanan Anda. Lakukan ini dengan mengganti localhost dengan nama domain server yang sepenuhnya memenuhi syarat.
Salin file Client.cer dari direktori klien ke direktori layanan di server.
Pada klien, jalankan ImportServiceCert.bat di Prompt Perintah Pengembang untuk Visual Studio yang dibuka dengan privilese administrator. Ini mengimpor sertifikat layanan dari file Service.cer ke penyimpanan CurrentUser - TrustedPeople.
Di server, jalankan ImportClientCert.bat di Prompt Perintah Pengembang untuk Visual Studio yang dibuka dengan hak istimewa administrator. Ini mengimpor sertifikat klien dari file Client.cer ke penyimpanan LocalMachine - TrustedPeople.
Di komputer server, luncurkan Service.exe dari jendela prompt perintah.
Di komputer klien, luncurkan Client.exe dari jendela prompt perintah. Jika klien dan layanan tidak dapat berkomunikasi, lihat Tips Pemecahan Masalah untuk Sampel WCF.
Untuk membersihkan setelah pengujian sampel
- Jalankan Cleanup.bat di folder sampel setelah Anda selesai menjalankan sampel. Ini menghapus sertifikat server dan klien dari penyimpanan sertifikat.
Nota
Skrip ini tidak menghapus sertifikat layanan pada klien saat menjalankan sampel ini di seluruh komputer. Jika Anda telah menjalankan sampel Windows Communication Foundation (WCF) yang menggunakan sertifikat di seluruh komputer, pastikan untuk menghapus sertifikat layanan yang telah diinstal di penyimpanan CurrentUser - TrustedPeople. Untuk melakukan ini, gunakan perintah berikut: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name> Misalnya: certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com.