Delegasi dan Peniruan dengan WCF
Peniruan dalah teknik umum yang digunakan layanan untuk membatasi akses klien ke sumber daya domain layanan. Sumber daya domain layanan dapat berupa sumber daya mesin, seperti file lokal (peniruan), atau sumber daya di komputer lain, seperti berbagi file (delegasi). Untuk aplikasi sampel, lihat Meniru Klien. Untuk contoh cara menggunakan peniruan, lihat Cara: Meniru Klien pada Layanan.
Penting
Ketahuilah bahwa saat meniru klien pada layanan, layanan berjalan dengan mandat klien, yang mungkin memiliki hak istimewa yang lebih tinggi daripada proses server.
Gambaran Umum
Biasanya, klien memanggil layanan agar layanan melakukan beberapa tindakan atas nama klien. Peniruan memungkinkan layanan untuk bertindak sebagai klien saat melakukan tindakan. Delegasi memungkinkan layanan front-end meneruskan permintaan klien ke layanan back-end sedemikian rupa sehingga layanan back-end juga dapat meniru klien. Peniruan paling umum digunakan sebagai cara untuk memeriksa apakah klien berwenang untuk melakukan tindakan tertentu, sementara delegasi adalah cara mengalirkan kemampuan peniruan identitas, bersama dengan identitas klien, ke layanan back-end. Delegasi adalah fitur domain Windows yang dapat digunakan saat autentikasi berbasis Kerberos dilakukan. Delegasi berbeda dari alur identitas dan, karena delegasi mentransfer kemampuan untuk meniru klien tanpa memiliki kata sandi klien, ini merupakan operasi istimewa yang jauh lebih tinggi daripada alur identitas.
Peniruan dan delegasi mengharuskan klien memiliki identitas Windows. Jika klien tidak memiliki identitas Windows, satu-satunya opsi yang tersedia adalah mengalirkan identitas klien ke layanan kedua.
Dasar-Dasar Peniruan
Windows Communication Foundation (WCF) mendukung peniruan untuk berbagai mandat klien. Topik ini menjelaskan dukungan model layanan untuk meniru pemanggil selama penerapan metode layanan. Yang juga dibahas adalah skenario penyebaran umum yang melibatkan opsi peniruan dan keamanan SOAP dan WCF dalam skenario ini.
Topik ini berfokus pada peniruan dan delegasi di WCF saat menggunakan keamanan SOAP. Anda juga dapat menggunakan peniruan dan delegasi dengan WCF saat menggunakan keamanan transportasi, seperti yang dijelaskan dalam Menggunakan Peniruan dengan Keamanan Transportasi.
Dua Metode
Keamanan WCF SOAP memiliki dua metode yang berbeda untuk melakukan peniruan. Metode yang digunakan tergantung pada pengikatannya. Salah satunya adalah peniruan dari token Windows yang diperoleh dari Antarmuka Penyedia Dukungan Keamanan (SSPI) atau autentikasi Kerberos, yang kemudian di-cache pada layanan. Yang kedua adalah peniruan dari token Windows yang diperoleh dari ekstensi Kerberos, yang secara kolektif disebut Service-for-User (S4U).
Peniruan Token Cache
Anda dapat melakukan peniruan token cache dengan yang berikut:
WSHttpBinding, WSDualHttpBinding, dan NetTcpBinding dengan mandat klien Windows.
BasicHttpBindingdengan BasicHttpSecurityMode diatur ke mandat TransportWithMessageCredential, atau pengikatan standar lainnya saat klien menyajikan mandat nama pengguna yang dapat dipetakan layanan ke akun Windows yang valid.
CustomBinding apa pun yang menggunakan mandat klien Windows dengan
requireCancellation
diatur ketrue
. (Properti tersedia pada kelas berikut: SecureConversationSecurityTokenParameters , SslSecurityTokenParameters, dan SspiSecurityTokenParameters.) Jika percakapan aman digunakan pada pengikatan, ini juga harus memiliki propertirequireCancellation
yang diatur ketrue
.CustomBinding apa pun yang mana klien menyajikan mandat nama pengguna. Jika percakapan aman digunakan pada pengikatan, properti
requireCancellation
juga harus diatur ketrue
.
Peniruan Berbasis S4U
Anda dapat melakukan peniruan berbasis S4U dengan yang berikut:
WSHttpBinding, WSDualHttpBinding, dan NetTcpBinding dengan mandat klien sertifikat yang dapat dipetakan layanan ke akun Windows yang valid.
CustomBinding apa pun yang menggunakan mandat klien Windows dengan properti
requireCancellation
diatur kefalse
.CustomBinding apa pun yang menggunakan nama pengguna atau mandat klien Windows dan percakapan aman dengan properti
requireCancellation
diatur kefalse
.
Sejauh mana layanan dapat meniru klien tergantung pada hak istimewa yang dipegang akun layanan saat mencoba peniruan, jenis peniruan yang digunakan, dan mungkin sejauh mana peniruan izin klien.
Catatan
Saat klien dan layanan berjalan di komputer yang sama dan klien berjalan dengan akun sistem (yakni Local System
atau Network Service
), klien tidak dapat ditiru saat sesi aman dibuat dengan token Konteks Keamanan stateful. Formulir Windows atau aplikasi konsol biasanya dijalankan dengan akun yang baru masuk, sehingga akun tersebut dapat ditiru secara default. Namun, jika klien adalah halaman ASP.NET dan halaman tersebut dihosting di IIS 6.0 atau IIS 7.0, klien akan dijalankan dengan akun Network Service
secara default. Semua binding yang disediakan sistem yang mendukung sesi aman menggunakan token konteks keamanan stateless (SCT) secara default. Namun, jika klien adalah halaman ASP.NET, dan sesi aman dengan SCT stateful digunakan, klien tidak dapat ditiru. Untuk mengetahui informasi selengkapnya tentang menggunakan SCT stateful dalam sesi aman, lihat Cara: Membuat Token Konteks Keamanan untuk Sesi Aman.
Peniruan dalam Metode Layanan: Model Deklaratif
Sebagian besar skenario peniruan melibatkan eksekusi metode layanan dalam konteks pemanggil. WCF menyediakan fitur peniruan yang memudahkan hal ini dengan memungkinkan pengguna menentukan persyaratan peniruan dalam atribut OperationBehaviorAttribute. Misalnya, dalam kode berikut, infrastruktur WCF meniru pemanggil sebelum menjalankan metode Hello
. Setiap upaya untuk mengakses sumber daya native di dalam metode Hello
hanya berhasil jika daftar kontrol akses (ACL) sumber daya memungkinkan hak istimewa akses pemanggil. Untuk mengaktifkan peniruan, atur properti Impersonation ke salah satu nilai enumerasi ImpersonationOption, baik ImpersonationOption.Required atau ImpersonationOption.Allowed, seperti yang ditunjukkan dalam contoh berikut.
Catatan
Saat layanan memiliki mandat yang lebih tinggi daripada klien jarak jauh, mandat layanan digunakan jika properti Impersonation diatur ke Allowed. Artinya, jika pengguna dengan hak istimewa rendah memberikan mandat, layanan dengan hak istimewa yang lebih tinggi menjalankan metode dengan mandat layanan, dan dapat menggunakan sumber daya yang tidak dapat digunakan oleh pengguna dengan hak istimewa rendah.
[ServiceContract]
public interface IHelloContract
{
[OperationContract]
string Hello(string message);
}
public class HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Hello(string message)
{
return "hello";
}
}
<ServiceContract()> _
Public Interface IHelloContract
<OperationContract()> _
Function Hello(ByVal message As String) As String
End Interface
Public Class HelloService
Implements IHelloService
<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
Return "hello"
End Function
End Class
Infrastruktur WCF dapat meniru pemanggil hanya jika pemanggil diautentikasi dengan mandat yang dapat dipetakan ke akun pengguna Windows. Jika layanan dikonfigurasi untuk mengautentikasi menggunakan mandat yang tidak dapat dipetakan ke akun Windows, metode layanan tidak dijalankan.
Catatan
Di Windows XP, peniruan gagal jika SCT stateful dibuat, menghasilkan InvalidOperationException. Untuk mengetahui informasi selengkapnya, lihat Skenario yang Tidak Didukung.
Peniruan dalam Metode Layanan: Model Imperatif
Terkadang pemanggil tidak perlu meniru seluruh metode layanan agar berfungsi, tetapi hanya untuk sebagian saja. Dalam hal ini, dapatkan identitas Windows pemanggil di dalam metode layanan dan secara imperatif melakukan peniruan. Lakukan ini dengan menggunakan properti WindowsIdentityServiceSecurityContext untuk mengembalikan instans kelas WindowsIdentity dan memanggil metode Impersonate sebelum menggunakan instans.
Catatan
Pastikan untuk menggunakan pernyataan Visual BasicUsing
atau pernyataan C# using
untuk secara otomatis mengembalikan tindakan peniruan identitas. Jika Anda tidak menggunakan pernyataan, atau jika Anda menggunakan bahasa pemrograman selain Visual Basic atau C#, pastikan untuk mengembalikan tingkat peniruan. Kegagalan untuk melakukan ini dapat membentuk dasar penolakan layanan dan peningkatan serangan hak istimewa.
public class HelloService : IHelloService
{
[OperationBehavior]
public string Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a WindowsIdentity");
}
using (callerWindowsIdentity.Impersonate())
{
// Access a file as the caller.
}
return "Hello";
}
}
Public Class HelloService
Implements IHelloService
<OperationBehavior()> _
Public Function Hello(ByVal message As String) As String _
Implements IHelloService.Hello
Dim callerWindowsIdentity As WindowsIdentity = _
ServiceSecurityContext.Current.WindowsIdentity
If (callerWindowsIdentity Is Nothing) Then
Throw New InvalidOperationException( _
"The caller cannot be mapped to a WindowsIdentity")
End If
Dim cxt As WindowsImpersonationContext = callerWindowsIdentity.Impersonate()
Using (cxt)
' Access a file as the caller.
End Using
Return "Hello"
End Function
End Class
Peniruan Untuk Semua Metode Layanan
Dalam beberapa kasus, Anda harus melakukan semua metode layanan dalam konteks pemanggil. Alih-alih secara eksplisit mengaktifkan fitur ini berdasarkan per metode, gunakan ServiceAuthorizationBehavior. Seperti yang ditunjukkan pada kode berikut, atur properti ImpersonateCallerForAllOperations ke true
. ServiceAuthorizationBehavior diambil dari kumpulan perilaku kelas ServiceHost. Perhatikan juga bahwa properti Impersonation
dari OperationBehaviorAttribute yang diterapkan ke setiap metode juga harus diatur ke Allowed atau Required.
// Code to create a ServiceHost not shown.
ServiceAuthorizationBehavior MyServiceAuthorizationBehavior =
serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = true;
' Code to create a ServiceHost not shown.
Dim MyServiceAuthorizationBehavior As ServiceAuthorizationBehavior
MyServiceAuthorizationBehavior = serviceHost.Description.Behaviors.Find _
(Of ServiceAuthorizationBehavior)()
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = True
Tabel berikut menjelaskan perilaku WCF untuk semua kemungkinan kombinasi ImpersonationOption
dan ImpersonateCallerForAllServiceOperations
.
ImpersonationOption |
ImpersonateCallerForAllServiceOperations |
Perilaku |
---|---|---|
Wajib | n/a | WCF meniru pemanggil |
Diizinkan | salah | WCF tidak meniru pemanggil |
Diizinkan | benar | WCF meniru pemanggil |
NotAllowed | salah | WCF tidak meniru pemanggil |
NotAllowed | benar | Tidak diizinkan. (InvalidOperationException dilemparkan.) |
Tingkat Peniruan Diperoleh dari Mandat Windows dan Peniruan Token Cache
Dalam beberapa skenario, klien memiliki kontrol parsial atas tingkat peniruan yang dilakukan layanan saat mandat klien Windows digunakan. Satu skenario terjadi saat klien menentukan tingkat peniruan anonim. Yang lain terjadi saat melakukan peniruan dengan token yang di-cache. Ini dilakukan dengan mengatur properti AllowedImpersonationLevel kelas WindowsClientCredential, yang diakses sebagai properti kelas ChannelFactory<TChannel> generik.
Catatan
Menentukan tingkat peniruan nama anonim menyebabkan klien masuk ke layanan secara anonim. Oleh karena itu, layanan harus mengizinkan masuk anonim, terlepas dari apakah peniruan dilakukan.
Klien dapat menentukan tingkat peniruan sebagai Anonymous, Identification, Impersonation, atau Delegation. Hanya token pada tingkat yang ditentukan yang diproduksi, seperti yang ditunjukkan dalam kode berikut.
ChannelFactory<IEcho> cf = new ChannelFactory<IEcho>("EchoEndpoint");
cf.Credentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
Dim cf As ChannelFactory(Of IEcho) = New ChannelFactory(Of IEcho)("EchoEndpoint")
cf.Credentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Impersonation
Tabel berikut menentukan tingkat peniruan yang diperoleh layanan saat meniru dari token yang di-cache.
AllowedImpersonationLevel nilai |
Layanan memiliki SeImpersonatePrivilege |
Layanan dan klien mampu mendelegasikan | Token yang di-cache ImpersonationLevel |
---|---|---|---|
Anonim | Ya | n/a | Peniruan |
Anonim | No | n/a | Identifikasi |
Identifikasi | n/a | n/a | Identifikasi |
Peniruan | Ya | n/a | Peniruan |
Peniruan | No | n/a | Identifikasi |
Delegasi | Ya | Ya | Delegasi |
Delegasi | Ya | Tidak | Peniruan |
Delegasi | No | n/a | Identifikasi |
Tingkat Peniruan Diperoleh dari Mandat Nama Pengguna dan Peniruan Token Cache
Dengan meneruskan layanan nama pengguna dan kata sandinya, klien memungkinkan WCF untuk masuk sebagai pengguna tersebut, yang setara dengan mengatur properti AllowedImpersonationLevel
ke Delegation. (AllowedImpersonationLevel
tersedia di kelas WindowsClientCredential dan HttpDigestClientCredential.) Tabel berikut ini menyediakan tingkat peniruan yang diperoleh saat layanan menerima mandat nama pengguna.
AllowedImpersonationLevel |
Layanan memiliki SeImpersonatePrivilege |
Layanan dan klien mampu mendelegasikan | Token yang di-cache ImpersonationLevel |
---|---|---|---|
n/a | Ya | Ya | Delegasi |
n/a | Ya | Tidak | Peniruan |
n/a | No | n/a | Identifikasi |
Tingkat Peniruan Diperoleh dari Peniruan Berbasis S4U
Layanan memiliki SeTcbPrivilege |
Layanan memiliki SeImpersonatePrivilege |
Layanan dan klien mampu mendelegasikan | Token yang di-cache ImpersonationLevel |
---|---|---|---|
Ya | Ya | n/a | Peniruan |
Ya | Tidak | n/a | Identifikasi |
No | n/a | n/a | Identifikasi |
Memetakan Sertifikat Klien ke Akun Windows
Klien dapat mengautentikasi dirinya sendiri ke layanan menggunakan sertifikat, dan meminta layanan memetakan klien ke akun yang ada melalui Direktori Aktif. XML berikut menunjukkan cara mengonfigurasi layanan untuk memetakan sertifikat.
<behaviors>
<serviceBehaviors>
<behavior name="MapToWindowsAccount">
<serviceCredentials>
<clientCertificate>
<authentication mapClientCertificateToWindowsAccount="true" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Kode berikut menunjukkan cara menghosting layanan.
// Create a binding that sets a certificate as the client credential type.
WSHttpBinding b = new WSHttpBinding();
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
// Create a service host that maps the certificate to a Windows account.
Uri httpUri = new Uri("http://localhost/Calculator");
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;
Delegasi
Untuk mendelegasikan ke layanan back-end, layanan harus melakukan multi-leg Kerberos (SSPI tanpa fallback NTLM) atau autentikasi langsung Kerberos ke layanan back-end menggunakan identitas Windows klien. Untuk mendelegasikan ke layanan back-end, buat ChannelFactory<TChannel> dan saluran, lalu komunikasikan melalui saluran sambil meniru klien. Dengan bentuk delegasi ini, jarak yang mana layanan back-end dapat ditemukan dari layanan front-end tergantung pada tingkat peniruan yang dicapai oleh layanan front-end. Saat tingkat peniruan adalah Impersonation, layanan front-end dan back-end harus berjalan pada komputer yang sama. Saat tingkat peniruan identitas adalah Delegation, layanan front-end dan back-end dapat berada di komputer yang terpisah atau di komputer yang sama. Mengaktifkan peniruan identitas tingkat delegasi mengharuskan kebijakan domain Windows dikonfigurasi untuk mengizinkan delegasi. Untuk mengetahui informasi selengkapnya tentang mengonfigurasi Direktori Aktif untuk dukungan delegasi, lihat Mengaktifkan Autentikasi yang Didelegasikan.
Catatan
Saat klien mengautentikasi ke layanan front-end menggunakan nama pengguna dan kata sandi yang sesuai dengan akun Windows pada layanan back-end, layanan front-end dapat mengautentikasi ke layanan back-end dengan menggunakan kembali nama pengguna dan kata sandi klien. Ini adalah bentuk alur identitas yang sangat kuat, karena meneruskan nama pengguna dan kata sandi ke layanan back-end memungkinkan layanan back-end melakukan peniruan, tetapi bukan merupakan delegasi karena Kerberos tidak digunakan. Kontrol Direktori Aktif pada delegasi tidak berlaku untuk autentikasi nama pengguna dan kata sandi.
Kemampuan Delegasi sebagai Fungsi Tingkat Peniruan
Tingkat peniruan | Layanan dapat melakukan delegasi lintas proses | Layanan dapat melakukan delegasi lintas komputer |
---|---|---|
Identification | Tidak | No |
Impersonation | Ya | No |
Delegation | Ya | Ya |
Contoh kode berikut menunjukkan cara menggunakan delegasi.
public class HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Hello(string message)
{
WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a Windows identity.");
}
using (callerWindowsIdentity.Impersonate())
{
EndpointAddress backendServiceAddress = new EndpointAddress("http://localhost:8000/ChannelApp");
// Any binding that performs Windows authentication of the client can be used.
ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>(new NetTcpBinding(), backendServiceAddress);
IHelloService channel = channelFactory.CreateChannel();
return channel.Hello(message);
}
}
}
Public Class HelloService
Implements IHelloService
<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
Dim callerWindowsIdentity As WindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity
If (callerWindowsIdentity Is Nothing) Then
Throw New InvalidOperationException("The caller cannot be mapped to a Windows identity.")
End If
Dim backendServiceAddress As EndpointAddress = New EndpointAddress("http://localhost:8000/ChannelApp")
' Any binding that performs Windows authentication of the client can be used.
Dim channelFactory As ChannelFactory(Of IHelloService) = _
New ChannelFactory(Of IHelloService)(New NetTcpBinding(), backendServiceAddress)
Dim channel As IHelloService = channelFactory.CreateChannel()
Return channel.Hello(message)
End Function
End Class
Cara Mengonfigurasi Aplikasi untuk Menggunakan Delegasi yang Dibatasi
Sebelum Anda dapat menggunakan delegasi yang dibatasi, pengirim, penerima, dan pengontrol domain harus dikonfigurasi untuk melakukannya. Prosedur berikut ini mencantumkan langkah-langkah yang mengaktifkan delegasi yang dibatasi. Untuk detail tentang perbedaan antara delegasi dan delegasi yang dibatasi, lihat bagian Ekstensi Kerberos Windows Server 2003 yang membahas diskusi yang dibatasi.
Pada pengendali domain, kosongkan kotak centang Akun sensitif dan tidak dapat didelegasikan untuk akun tempat aplikasi klien berjalan.
Pada pengendali domain, pilih kotak centang Akun dipercaya untuk delegasi untuk akun yang menjalankan aplikasi klien.
Pada pengendali domain, konfigurasikan komputer tingkat tengah sehingga dipercaya untuk delegasi, dengan mengeklik opsi Percayai komputer untuk delegasi.
Pada pengendali domain, konfigurasikan komputer tingkat menengah untuk menggunakan delegasi terbatas, dengan mengeklik opsi Percayai komputer ini untuk delegasi ke layanan tertentu saja.
Untuk instruksi lebih rinci tentang mengonfigurasi delegasi yang dibatasi, lihat Transisi Protokol Kerberos dan Delegasi yang Dibatasi.
Lihat juga
- OperationBehaviorAttribute
- Impersonation
- ImpersonationOption
- WindowsIdentity
- ServiceSecurityContext
- WindowsIdentity
- ServiceAuthorizationBehavior
- ImpersonateCallerForAllOperations
- ServiceHost
- AllowedImpersonationLevel
- WindowsClientCredential
- ChannelFactory<TChannel>
- Identification
- Menggunakan Peniruan Identitas dengan Keamanan Transportasi
- Meniru Klien
- Cara: Meniru Klien pada Layanan
- Alat Utilitas Metadata ServiceModel (Svcutil.exe)