Bagikan melalui


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:

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 ke false.

  • CustomBinding apa pun yang menggunakan nama pengguna atau mandat klien Windows dan percakapan aman dengan properti requireCancellation diatur ke false.

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.

  1. Pada pengendali domain, kosongkan kotak centang Akun sensitif dan tidak dapat didelegasikan untuk akun tempat aplikasi klien berjalan.

  2. Pada pengendali domain, pilih kotak centang Akun dipercaya untuk delegasi untuk akun yang menjalankan aplikasi klien.

  3. Pada pengendali domain, konfigurasikan komputer tingkat tengah sehingga dipercaya untuk delegasi, dengan mengeklik opsi Percayai komputer untuk delegasi.

  4. 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