Bagikan melalui


Cara: Membuat Pengelola Otorisasi Kustom untuk Layanan

Infrastruktur Model Identitas di Windows Communication Foundation (WCF) mendukung model otorisasi berbasis klaim yang dapat diperluas. Klaim diekstrak dari token dan secara opsional diproses oleh kebijakan otorisasi kustom dan kemudian ditempatkan ke dalam AuthorizationContext. Pengelola otorisasi memeriksa klaim dalam AuthorizationContext untuk membuat keputusan otorisasi.

Secara default, keputusan otorisasi dibuat oleh kelas ServiceAuthorizationManager; tetapi keputusan ini dapat ditimpa dengan membuat pengelola otorisasi kustom. Untuk membuat pengelola otorisasi kustom, buat kelas yang merupakan turunan dari ServiceAuthorizationManager dan implementasikan metode CheckAccessCore. Keputusan otorisasi dibuat dalam metode CheckAccessCore, yang menampilkan true saat akses diberikan dan false saat akses ditolak.

Jika keputusan otorisasi bergantung pada konten isi pesan, gunakan metode CheckAccess.

Karena masalah performa, jika mungkin Anda harus mendesain ulang aplikasi Anda sehingga keputusan otorisasi tidak memerlukan akses ke isi pesan.

Pendaftaran pengelola otorisasi khusus untuk suatu layanan dapat dilakukan dalam kode atau konfigurasi.

Untuk membuat pengelola otorisasi kustom

  1. Dapatkan turunan kelas dari kelas ServiceAuthorizationManager.

    public class MyServiceAuthorizationManager : ServiceAuthorizationManager
    {
    
    
    Public Class MyServiceAuthorizationManager
        Inherits ServiceAuthorizationManager
    
    
  2. Ambil alih metode CheckAccessCore(OperationContext).

    Gunakan OperationContext yang diteruskan ke metode CheckAccessCore(OperationContext) untuk membuat keputusan otorisasi.

    Contoh kode berikut menggunakan metode FindClaims(String, String) untuk menemukan klaim http://www.contoso.com/claims/allowedoperation kustom untuk membuat keputusan otorisasi.

    protected override bool CheckAccessCore(OperationContext operationContext)
    {
      // Extract the action URI from the OperationContext. Match this against the claims
      // in the AuthorizationContext.
      string action = operationContext.RequestContext.RequestMessage.Headers.Action;
    
      // Iterate through the various claim sets in the AuthorizationContext.
      foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
      {
        // Examine only those claim sets issued by System.
        if (cs.Issuer == ClaimSet.System)
        {
          // Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
            foreach (Claim c in cs.FindClaims("http://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
          {
            // If the Claim resource matches the action URI then return true to allow access.
            if (action == c.Resource.ToString())
              return true;
          }
        }
      }
    
      // If this point is reached, return false to deny access.
      return false;
    }
    
    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action
    
        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs
        ' If this point is reached, return false to deny access.
        Return False
    
    End Function
    

Untuk mendaftarkan pengelola otorisasi kustom menggunakan kode

  1. Buat instans pengelola otorisasi kustom dan tetapkan ke properti ServiceAuthorizationManager.

    ServiceAuthorizationBehavior dapat diakses menggunakan properti Authorization.

    Contoh kode berikut mendaftarkan pengelola otorisasi kustom MyServiceAuthorizationManager.

    // Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager =
               new MyServiceAuthorizationManager();
    
    ' Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager = _
        New MyServiceAuthorizationManager()
    
    

Untuk mendaftarkan pengelola otorisasi kustom menggunakan konfigurasi

  1. Buka file konfigurasi untuk layanan.

  2. Tambahkan <serviceAuthorization> ke <perilaku>.

    Pada <serviceAuthorization>, tambahkan atribut serviceAuthorizationManagerType dan atur nilainya ke jenis yang mewakili pengelola otorisasi kustom.

  3. Tambahkan pengikatan yang mengamankan komunikasi antara klien dan layanan.

    Pengikatan yang dipilih untuk komunikasi ini menentukan klaim yang ditambahkan ke AuthorizationContext, yang digunakan pengelola otorisasi kustom untuk membuat keputusan otorisasi. Untuk detail selengkapnya tentang pengikatan yang disediakan sistem, lihat Pengikatan yang Disediakan Sistem.

  4. Kaitkan perilaku ke titik akhir layanan, dengan menambahkan elemen <layanan> dan mengatur nilai atribut behaviorConfiguration ke nilai atribut nama untuk elemen <perilaku>.

    Untuk informasi selengkapnya, lihat Cara: Membuat Titik Akhir Layanan dalam Konfigurasi.

    Contoh kode berikut mendaftarkan pengelola otorisasi kustom Samples.MyServiceAuthorizationManager.

    <configuration>
      <system.serviceModel>
        <services>
          <service
              name="Microsoft.ServiceModel.Samples.CalculatorService"
              behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
              </baseAddresses>
            </host>
            <endpoint address=""
                      binding="wsHttpBinding_Calculator"
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
          </service>
        </services>
        <bindings>
          <WSHttpBinding>
           <binding name = "wsHttpBinding_Calculator">
             <security mode="Message">
               <message clientCredentialType="Windows"/>
             </security>
            </binding>
          </WSHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceAuthorization serviceAuthorizationManagerType="Samples.MyServiceAuthorizationManager,MyAssembly" />
             </behavior>
         </serviceBehaviors>
       </behaviors>
      </system.serviceModel>
    </configuration>
    

    Peringatan

    Perhatikan bahwa saat Anda menentukan serviceAuthorizationManagerType, string harus berisi nama jenis yang sepenuhnya memenuhi syarat. koma, dan nama rakitan di mana jenis didefinisikan. Jika Anda membiarkan nama rakitan, WCF akan mencoba memuat jenis dari System.ServiceModel.dll.

Contoh

Contoh kode berikut menunjukkan implementasi dasar kelas ServiceAuthorizationManager yang meliputi penimpaan metode CheckAccessCore. Contoh kode memeriksa AuthorizationContext untuk klaim kustom dan menampilkan true saat sumber daya untuk klaim kustom tersebut cocok dengan nilai tindakan dari OperationContext. Untuk implementasi kelas ServiceAuthorizationManager yang lebih lengkap, lihat Kebijakan Otorisasi.

public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
  protected override bool CheckAccessCore(OperationContext operationContext)
  {
    // Extract the action URI from the OperationContext. Match this against the claims
    // in the AuthorizationContext.
    string action = operationContext.RequestContext.RequestMessage.Headers.Action;
  
    // Iterate through the various claim sets in the AuthorizationContext.
    foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
    {
      // Examine only those claim sets issued by System.
      if (cs.Issuer == ClaimSet.System)
      {
        // Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
          foreach (Claim c in cs.FindClaims("http://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
        {
          // If the Claim resource matches the action URI then return true to allow access.
          if (action == c.Resource.ToString())
            return true;
        }
      }
    }
  
    // If this point is reached, return false to deny access.
    return false;
  }
}

Public Class MyServiceAuthorizationManager
    Inherits ServiceAuthorizationManager

    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action

        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs
        ' If this point is reached, return false to deny access.
        Return False

    End Function
End Class

Lihat juga