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 kebijakan otorisasi klaim kustom dan manajer otorisasi layanan kustom terkait. Ini berguna ketika layanan melakukan pemeriksaan akses berbasis klaim ke operasi layanan dan sebelum pemeriksaan akses, memberikan hak tertentu kepada pemanggil. Sampel ini menunjukkan proses penambahan klaim serta proses untuk melakukan pemeriksaan akses terhadap serangkaian klaim yang diselesaikan. Semua pesan aplikasi antara klien dan server ditandatangani dan dienkripsi. Secara default dengan pengikatan wsHttpBinding , nama pengguna dan kata sandi yang disediakan oleh klien digunakan untuk masuk ke akun Windows yang valid. Sampel ini menunjukkan cara menggunakan kustom UserNamePasswordValidator untuk mengautentikasi klien. Selain itu, sampel ini menunjukkan klien yang mengautentikasi ke layanan menggunakan sertifikat X.509. Sampel ini menunjukkan implementasi IAuthorizationPolicy dan ServiceAuthorizationManager, yang di antaranya memberikan akses ke metode layanan tertentu untuk pengguna tertentu. Sampel ini didasarkan pada Nama Pengguna Keamanan Pesan, tetapi menunjukkan cara melakukan transformasi klaim sebelum dipanggil ServiceAuthorizationManager .
Nota
Prosedur penyiapan dan instruksi build untuk sampel ini terletak di akhir topik ini.
Singkatnya, sampel ini menunjukkan cara:
Klien dapat diautentikasi menggunakan nama pengguna-kata sandi.
Klien dapat diautentikasi menggunakan sertifikat X.509.
Server memvalidasi kredensial klien terhadap validator kustom
UsernamePassword.Server diautentikasi menggunakan sertifikat X.509 server.
Server dapat menggunakan ServiceAuthorizationManager untuk mengontrol akses ke metode tertentu dalam layanan.
Cara mengimplementasikan IAuthorizationPolicy.
Layanan ini mengekspos dua titik akhir untuk berkomunikasi dengan layanan, yang ditentukan menggunakan file konfigurasi App.config. Setiap titik akhir terdiri dari alamat, pengikatan, dan kontrak. Satu pengikatan dikonfigurasi dengan pengikatan standar wsHttpBinding yang menggunakan WS-Security dan autentikasi nama pengguna klien. Pengikatan lainnya dikonfigurasi dengan pengikatan standar wsHttpBinding yang menggunakan WS-Security dan autentikasi sertifikat klien.
Perilaku<> menentukan bahwa kredensial pengguna akan digunakan untuk autentikasi layanan. Sertifikat server harus berisi nilai yang sama untuk SubjectName properti sebagai findValue atribut dalam <serviceCertificate>.
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<!-- configure base address provided by host -->
<add baseAddress ="http://localhost:8001/servicemodelsamples/service"/>
</baseAddresses>
</host>
<!-- use base address provided by host, provide two endpoints -->
<endpoint address="username"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="certificate"
binding="wsHttpBinding"
bindingConfiguration="Binding2"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
</services>
<bindings>
<wsHttpBinding>
<!-- Username binding -->
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
<!-- X509 certificate binding -->
<binding name="Binding2">
<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 a custom validator for username/password combinations.
-->
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.MyCustomUserNameValidator, service" />
<!--
The serviceCredentials behavior allows one to specify authentication constraints on client certificates.
-->
<clientCertificate>
<!--
Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
is in the user's Trusted People store, then it will be 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" />
</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>
<serviceAuthorization serviceAuthorizationManagerType="Microsoft.ServiceModel.Samples.MyServiceAuthorizationManager, service">
<!--
The serviceAuthorization behavior allows one to specify custom authorization policies.
-->
<authorizationPolicies>
<add policyType="Microsoft.ServiceModel.Samples.CustomAuthorizationPolicy.MyAuthorizationPolicy, PolicyLibrary" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Setiap konfigurasi titik akhir klien terdiri dari nama konfigurasi, alamat absolut untuk titik akhir layanan, pengikatan, dan kontrak. Pengikatan klien dikonfigurasi dengan mode keamanan yang sesuai seperti yang ditentukan dalam kasus ini dalam <keamanan> dan clientCredentialType seperti yang ditentukan dalam <pesan>.
<system.serviceModel>
<client>
<!-- Username based endpoint -->
<endpoint name="Username"
address="http://localhost:8001/servicemodelsamples/service/username"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
behaviorConfiguration="ClientCertificateBehavior"
contract="Microsoft.ServiceModel.Samples.ICalculator" >
</endpoint>
<!-- X509 certificate based endpoint -->
<endpoint name="Certificate"
address="http://localhost:8001/servicemodelsamples/service/certificate"
binding="wsHttpBinding"
bindingConfiguration="Binding2"
behaviorConfiguration="ClientCertificateBehavior"
contract="Microsoft.ServiceModel.Samples.ICalculator">
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<!-- Username binding -->
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
<!-- X509 certificate binding -->
<binding name="Binding2">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<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 will be
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>
</behaviors>
</system.serviceModel>
Untuk titik akhir berbasis nama pengguna, implementasi klien mengatur nama pengguna dan kata sandi yang akan digunakan.
// Create a client with Username endpoint configuration
CalculatorClient client1 = new CalculatorClient("Username");
client1.ClientCredentials.UserName.UserName = "test1";
client1.ClientCredentials.UserName.Password = "1tset";
try
{
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client1.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
...
}
catch (Exception e)
{
Console.WriteLine("Call failed : {0}", e.Message);
}
client1.Close();
Untuk titik akhir berbasis sertifikat, implementasi klien mengatur sertifikat klien untuk digunakan.
// Create a client with Certificate endpoint configuration
CalculatorClient client2 = new CalculatorClient("Certificate");
client2.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "test1");
try
{
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client2.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
...
}
catch (Exception e)
{
Console.WriteLine("Call failed : {0}", e.Message);
}
client2.Close();
Sampel ini menggunakan kustom UserNamePasswordValidator untuk memvalidasi nama pengguna dan kata sandi. Sampel mengimplementasikan MyCustomUserNamePasswordValidator, berasal dari UserNamePasswordValidator. Lihat dokumentasi tentang UserNamePasswordValidator untuk informasi selengkapnya. Untuk tujuan menunjukkan integrasi dengan , sampel validator kustom ini mengimplementasikan UserNamePasswordValidator metode untuk menerima pasangan nama pengguna/kata sandi di mana nama pengguna cocok dengan Validatekata sandi seperti yang ditunjukkan dalam kode berikut.
public class MyCustomUserNamePasswordValidator : UserNamePasswordValidator
{
// This method validates users. It allows in two users,
// test1 and test2 with passwords 1tset and 2tset respectively.
// This code is for illustration purposes only and
// MUST NOT be used in a production environment because it
// is NOT secure.
public override void Validate(string userName, string password)
{
if (null == userName || null == password)
{
throw new ArgumentNullException();
}
if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
{
throw new SecurityTokenException("Unknown Username or Password");
}
}
}
Setelah validator diterapkan dalam kode layanan, host layanan harus diberi tahu tentang instans validator yang akan digunakan. Ini dilakukan menggunakan kode berikut:
Servicehost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new MyCustomUserNamePasswordValidatorProvider();
Atau Anda dapat melakukan hal yang sama dalam konfigurasi:
<behavior>
<serviceCredentials>
<!--
The serviceCredentials behavior allows one to specify a custom validator for username/password combinations.
-->
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.MyCustomUserNameValidator, service" />
...
</serviceCredentials>
</behavior>
Windows Communication Foundation (WCF) menyediakan model berbasis klaim yang kaya untuk melakukan pemeriksaan akses. Objek ServiceAuthorizationManager digunakan untuk melakukan pemeriksaan akses dan menentukan apakah klaim yang terkait dengan klien memenuhi persyaratan yang diperlukan untuk mengakses metode layanan.
Untuk tujuan demonstrasi, sampel ini menunjukkan implementasi ServiceAuthorizationManager yang mengimplementasikan CheckAccessCore metode untuk memungkinkan akses pengguna ke metode berdasarkan klaim jenis http://example.com/claims/allowedoperation yang nilainya adalah URI Tindakan dari operasi yang diizinkan untuk dipanggil.
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
string action = operationContext.RequestContext.RequestMessage.Headers.Action;
Console.WriteLine("action: {0}", action);
foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
{
if ( cs.Issuer == ClaimSet.System )
{
foreach (Claim c in cs.FindClaims("http://example.com/claims/allowedoperation", Rights.PossessProperty))
{
Console.WriteLine("resource: {0}", c.Resource.ToString());
if (action == c.Resource.ToString())
return true;
}
}
}
return false;
}
}
Setelah kustom ServiceAuthorizationManager diterapkan, host layanan harus diberi tahu tentang ServiceAuthorizationManager yang harus digunakan. Ini dilakukan seperti yang ditunjukkan dalam kode berikut.
<behavior>
...
<serviceAuthorization serviceAuthorizationManagerType="Microsoft.ServiceModel.Samples.MyServiceAuthorizationManager, service">
...
</serviceAuthorization>
</behavior>
Metode IAuthorizationPolicy utama yang harus diimplementasikan adalah metode Evaluate(EvaluationContext, Object).
public class MyAuthorizationPolicy : IAuthorizationPolicy
{
string id;
public MyAuthorizationPolicy()
{
id = Guid.NewGuid().ToString();
}
public bool Evaluate(EvaluationContext evaluationContext,
ref object state)
{
bool bRet = false;
CustomAuthState customstate = null;
if (state == null)
{
customstate = new CustomAuthState();
state = customstate;
}
else
customstate = (CustomAuthState)state;
Console.WriteLine("In Evaluate");
if (!customstate.ClaimsAdded)
{
IList<Claim> claims = new List<Claim>();
foreach (ClaimSet cs in evaluationContext.ClaimSets)
foreach (Claim c in cs.FindClaims(ClaimTypes.Name,
Rights.PossessProperty))
foreach (string s in
GetAllowedOpList(c.Resource.ToString()))
{
claims.Add(new
Claim("http://example.com/claims/allowedoperation",
s, Rights.PossessProperty));
Console.WriteLine("Claim added {0}", s);
}
evaluationContext.AddClaimSet(this,
new DefaultClaimSet(this.Issuer,claims));
customstate.ClaimsAdded = true;
bRet = true;
}
else
{
bRet = true;
}
return bRet;
}
...
}
Kode sebelumnya menunjukkan bagaimana Evaluate(EvaluationContext, Object) metode memeriksa bahwa tidak ada klaim baru yang telah ditambahkan yang memengaruhi pemrosesan dan menambahkan klaim tertentu. Klaim yang diizinkan diperoleh dari GetAllowedOpList metode , yang diimplementasikan untuk mengembalikan daftar operasi tertentu yang diizinkan untuk dilakukan pengguna. Kebijakan otorisasi menambahkan klaim untuk mengakses operasi tertentu. Ini kemudian digunakan oleh ServiceAuthorizationManager untuk melakukan keputusan pemeriksaan akses.
Setelah kustom IAuthorizationPolicy diterapkan, host layanan harus diberi tahu tentang kebijakan otorisasi yang akan digunakan.
<serviceAuthorization>
<authorizationPolicies>
<add policyType='Microsoft.ServiceModel.Samples.CustomAuthorizationPolicy.MyAuthorizationPolicy, PolicyLibrary' />
</authorizationPolicies>
</serviceAuthorization>
Saat Anda menjalankan sampel, permintaan dan respons operasi ditampilkan di jendela konsol klien. Klien berhasil memanggil metode Tambahkan, Kurangi, dan Beberapa dan mendapatkan pesan "Akses ditolak" saat mencoba memanggil metode Bagi. 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.
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 server. Nilai ini diatur ke "test1" karena ini adalah nama yang dicari
IAuthorizationPolicy. Jika Anda mengubah nilai %USER_NAME% Anda harus mengubah nilai yang sesuai dalamIAuthorizationPolicy.Evaluatemetode .Sertifikat disimpan di penyimpanan Saya (Pribadi) di bawah lokasi penyimpanan CurrentUser.
echo ************ echo making client cert echo ************ makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%CLIENT_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 %CLIENT_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.
Nota
Jika Anda menggunakan Svcutil.exe untuk meregenerasi konfigurasi untuk sampel ini, pastikan untuk mengubah nama titik akhir dalam konfigurasi klien agar sesuai dengan kode klien.
Untuk menjalankan sampel pada komputer yang sama
Buka Perintah Pengembang untuk Visual Studio dengan hak istimewa administrator dan jalankan Setup.bat dari folder instalasi sampel. Ini menginstal semua sertifikat yang diperlukan untuk menjalankan sampel.
Nota
File batch Setup.bat dirancang untuk dijalankan dari Developer Command Prompt untuk Visual Studio. Variabel lingkungan PATH diatur dalam Developer Command Prompt untuk 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 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.Menjalankan
setup.batdengan argumenservicemembuat sertifikat layanan dengan nama domain lengkap dari komputer, dan mengekspor sertifikat layanan tersebut 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.Menjalankan
setup.batargumenclientmembuat sertifikat klien bernama test1 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 hak istimewa 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.
Bersihkan setelah sampel
Untuk membersihkan setelah 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 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.