Bagikan melalui


Federasi

Topik ini memberikan ringkasan singkat tentang konsep keamanan federasi. Topik ini juga menjelaskan dukungan Windows Communication Foundation (WCF) untuk menyebarkan arsitektur keamanan gabungan. Untuk contoh aplikasi yang menunjukkan federasi, baca Contoh Federasi.

Definisi Keamanan Federasi

Keamanan gabungan memungkinkan pemisahan yang mulus antara layanan yang diakses klien dan prosedur autentikasi dan otorisasi terkait. Keamanan gabungan juga memungkinkan kolaborasi di berbagai sistem, jaringan, dan organisasi di berbagai bidang kepercayaan.

WCF menyediakan dukungan untuk membangun dan menyebarkan sistem terdistribusi yang menggunakan keamanan gabungan.

Elemen Arsitektur Keamanan Federasi

Arsitektur keamanan federasi memiliki tiga elemen kunci, seperti yang dijelaskan dalam tabel berikut.

Elemen Deskripsi
Domain/realm Sebuah unit administrasi keamanan atau kepercayaan. Domain tipikal yang mungkin mencakup satu organisasi.
Federasi Kumpulan domain yang telah membangun kepercayaan. Tingkat kepercayaan dapat bervariasi, tetapi biasanya mencakup autentikasi dan hampir selalu menyertakan otorisasi. Federasi umum mungkin mencakup sejumlah organisasi yang sudah membangun kepercayaan untuk akses bersama ke sekumpulan sumber daya.
Layanan Token Keamanan (STS) Layanan Web yang mengeluarkan token keamanan; yaitu layanan yang membuat pernyataan berdasarkan bukti yang dipercayainya, kepada siapa pun yang memercayainya. Cara ini membentuk dasar perantara kepercayaan antar domain.

Contoh Skenario

Ilustrasi berikut menunjukkan contoh keamanan gabungan:

Diagram showing a typical federated security scenario.

Skenario ini mencakup dua organisasi: A dan B. Organisasi B memiliki sumber daya Web (layanan Web) yang menurut beberapa pengguna di organisasi A berharga.

Catatan

Bagian ini menggunakan istilah sumber daya, layanan, dan layanan Web secara bergantian.

Biasanya, organisasi B mengharuskan pengguna dari organisasi A menyediakan beberapa bentuk autentikasi yang valid sebelum mengakses layanan. Selain itu, organisasi mungkin juga mengharuskan pengguna diberi otorisasi untuk mengakses sumber daya tertentu yang bersangkutan. Salah satu cara untuk mengatasi masalah ini dan memungkinkan pengguna di organisasi A untuk mengakses sumber daya di organisasi B adalah sebagai berikut:

  • Pengguna dari organisasi A mendaftarkan kredensial mereka (nama pengguna dan kata sandi) dengan organisasi B.

  • Selama akses sumber daya, pengguna dari organisasi A mempresentasikan kredensial mereka ke organisasi B dan diautentikasi sebelum mengakses sumber daya.

Pendekatan ini memiliki tiga kelemahan yang signifikan:

  • Organisasi B harus mengelola kredensial untuk pengguna dari organisasi A selain mengelola kredensial pengguna lokalnya.

  • Pengguna dalam organisasi A perlu memelihara kumpulan kredensial (yaitu, mengingat nama pengguna dan sandi tambahan) selain dari kredensial yang biasanya mereka gunakan untuk mendapatkan akses ke sumber daya dalam organisasi A. Operasi ini biasanya menganjurkan praktik menggunakan nama pengguna dan kata sandi yang sama di beberapa situs layanan, yang merupakan langkah keamanan yang lemah.

  • Arsitektur tidak berskala karena lebih banyak organisasi menganggap sumber daya di organisasi B memiliki nilai tertentu.

Pendekatan alternatif, yang mengatasi kelemahan yang disebutkan sebelumnya, adalah menggunakan keamanan gabungan. Dalam pendekatan ini, organisasi A dan B membangun hubungan saling percaya dan menggunakan Layanan Token Keamanan (STS) untuk memungkinkan perantara kepercayaan yang sudah tersambung.

Dalam arsitektur keamanan gabungan, pengguna dari organisasi A tahu bahwa jika mereka ingin mengakses layanan Web di organisasi B, mereka harus menunjukkan token keamanan yang valid dari STS di organisasi B, yang mengautentikasi dan mengotorisasi akses mereka ke layanan tertentu.

Saat menghubungi STS B, pengguna menerima tingkat tidak langsung lain dari kebijakan yang terkait dengan STS. Mereka harus menunjukkan token keamanan yang valid dari STS A (yaitu, realm kepercayaan klien) sebelum STS B dapat mengeluarkan token keamanan kepada pengguna. Proses ini adalah konsekuen yang wajar dari hubungan kepercayaan yang terjalin antara dua organisasi dan menyiratkan bahwa organisasi B tidak harus mengelola identitas untuk pengguna dari organisasi A. Dalam praktiknya, STS B biasanya memiliki null issuerAddress dan issuerMetadataAddress. Untuk informasi selengkapnya, baca Cara: Mengonfigurasi Penerbit Lokal. Dalam hal ini, klien berkonsultasi dengan kebijakan lokal untuk menemukan STS A. Konfigurasi ini disebut home realm federation dan skalanya lebih baik karena STS B tidak harus menyimpan informasi tentang STS A.

Pengguna kemudian menghubungi STS di organisasi A dan mendapatkan token keamanan dengan menunjukkan kredensial autentikasi yang biasanya mereka gunakan untuk mendapatkan akses ke sumber daya lain dalam organisasi A. Cara ini juga mengurangi masalah pengguna yang harus memelihara beberapa kumpulan kredensial atau menggunakan kumpulan kredensial yang sama di beberapa situs layanan.

Setelah pengguna mendapatkan token keamanan dari STS A, pengguna memberikan token ke STS B. Organisasi B melanjutkan untuk melakukan otorisasi permintaan pengguna dan mengeluarkan token keamanan kepada pengguna dari kumpulan token keamanannya sendiri. Pengguna kemudian dapat menunjukkan token mereka ke sumber daya di organisasi B dan mengakses layanan.

Dukungan untuk Keamanan Federasi di WCF

WCF menyediakan dukungan turnkey untuk menyebarkan arsitektur keamanan federasi melalui <wsFederationHttpBinding>.

Elemen <wsFederationHttpBinding> menyediakan pengikatan yang aman, andal, dan dapat dioperasikan yang memerlukan penggunaan HTTP sebagai mekanisme transportasi yang mendasari gaya komunikasi permintaan-balasan, menggunakan teks dan XML sebagai format wire untuk pengkodean.

Penggunaan <wsFederationHttpBinding> dalam skenario keamanan federasi dapat dipisahkan menjadi dua fase yang independen secara logis, seperti yang dijelaskan di bagian berikut.

Fase 1: Fase Desain

Selama fase desain, klien menggunakan Alat Utilitas Metadata ServiceModel (Svcutil.exe) untuk membaca kebijakan yang diekspos titik akhir layanan dan untuk mengumpulkan persyaratan autentikasi dan otorisasi layanan. Proksi yang sesuai dibuat untuk membuat pola komunikasi keamanan gabungan berikut di klien:

  • Dapatkan token keamanan dari STS di ranah kepercayaan klien.

  • Tunjukkan token ke STS di realms kepercayaan layanan.

  • Dapatkan token keamanan dari STS di realm kepercayaan layanan.

  • Tunjukkan token ke layanan untuk mengakses layanan.

Fase 2: Fase Run-Time

Selama fase run-time, klien membuat instans objek kelas klien WCF dan membuat panggilan menggunakan klien WCF. Kerangka dasar WCF menangani langkah-langkah yang disebutkan sebelumnya dalam pola komunikasi keamanan gabungan dan memungkinkan klien untuk menggunakan layanan dengan mulus.

Contoh Implementasi Menggunakan WCF

Ilustrasi berikut menunjukkan contoh implementasi untuk arsitektur keamanan gabungan menggunakan dukungan asli dari WCF.

Diagram showing a sample Federation security implementation.

Contoh MyService

Layanan MyService mengekspos satu titik akhir melalui MyServiceEndpoint. Ilustrasi berikut menunjukkan alamat, pengikatan, dan kontrak yang terkait dengan titik akhir.

Diagram showing the MyServiceEndpoint details.

Titik akhir layanan MyServiceEndpoint menggunakan <wsFederationHttpBinding> dan memerlukan token Security Assertions Markup Language (SAML) yang valid dengan klaim accessAuthorized yang dikeluarkan oleh STS B. Operasi ini ditetapkan secara deklaratif dalam konfigurasi layanan.

<system.serviceModel>  
  <services>  
    <service type="FederationSample.MyService"
        behaviorConfiguration='MyServiceBehavior'>  
        <endpoint address=""  
            binding=" wsFederationHttpBinding"  
            bindingConfiguration='MyServiceBinding'  
            contract="Federation.IMyService" />  
   </service>  
  </services>  
  
  <bindings>  
    <wsFederationHttpBinding>  
    <!-- This is the binding used by MyService. It redirects   
    clients to STS-B. -->  
      <binding name='MyServiceBinding'>  
        <security mode="Message">  
           <message issuedTokenType=  
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">  
           <issuer address="http://localhost/FederationSample/STS-B/STS.svc" />  
            <issuerMetadata
           address=  
"http://localhost/FederationSample/STS-B/STS.svc/mex" />  
         <requiredClaimTypes>  
            <add claimType="http://tempuri.org:accessAuthorized" />  
         </requiredClaimTypes>  
        </message>  
      </security>  
      </binding>  
    </wsFederationHttpBinding>  
  </bindings>  
  
  <behaviors>  
    <behavior name='MyServiceBehavior'>  
      <serviceAuthorization
operationRequirementType="FederationSample.MyServiceOperationRequirement, MyService" />  
       <serviceCredentials>  
         <serviceCertificate findValue="CN=FederationSample.com"  
         x509FindType="FindBySubjectDistinguishedName"  
         storeLocation='LocalMachine'  
         storeName='My' />  
      </serviceCredentials>  
    </behavior>  
  </behaviors>  
</system.serviceModel>  

Catatan

Titik yang kentara harus diperhatikan tentang klaim yang perlukan oleh MyService. Gambar kedua menunjukkan bahwa MyService memerlukan token SAML dengan klaim accessAuthorized. Untuk lebih tepatnya, proses ini menentukan jenis klaim yang diperlukan MyService. Nama yang sepenuhnya memenuhi syarat dari jenis klaim ini adalah http://tempuri.org:accessAuthorized (bersama dengan namespace terkait), yang digunakan dalam file konfigurasi layanan. Nilai klaim ini menunjukkan adanya klaim ini dan diasumsikan untuk diatur menjadi true oleh STS B.

Saat dijalankan, kebijakan ini diberlakukan oleh kelas MyServiceOperationRequirement yang diimplementasikan sebagai bagian dari MyService.

using System.Collections.Generic;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
Imports System.Collections.Generic
Imports System.IdentityModel.Claims
Imports System.IdentityModel.Policy
Imports System.IdentityModel.Tokens
Imports System.Security.Cryptography.X509Certificates
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Security.Tokens
Imports System.Text
public class myServiceAuthorizationManager : ServiceAuthorizationManager
{
    // Override the CheckAccess method to enforce access control requirements.
    public override bool CheckAccess(OperationContext operationContext)
    {
        AuthorizationContext authContext =
        operationContext.ServiceSecurityContext.AuthorizationContext;
        if (authContext.ClaimSets == null) return false;
        if (authContext.ClaimSets.Count != 1) return false;
        ClaimSet myClaimSet = authContext.ClaimSets[0];
        if (!IssuedBySTS_B(myClaimSet)) return false;
        if (myClaimSet.Count != 1) return false;
        Claim myClaim = myClaimSet[0];
        if (myClaim.ClaimType ==
          "http://www.tmpuri.org:accessAuthorized")
        {
            string resource = myClaim.Resource as string;
            if (resource == null) return false;
            if (resource != "true") return false;
            return true;
        }
        else
        {
            return false;
        }
    }

    // This helper method checks whether SAML Token was issued by STS-B.
    // It compares the Thumbprint Claim of the Issuer against the
    // Certificate of STS-B.
    private bool IssuedBySTS_B(ClaimSet myClaimSet)
    {
        ClaimSet issuerClaimSet = myClaimSet.Issuer;
        if (issuerClaimSet == null) return false;
        if (issuerClaimSet.Count != 1) return false;
        Claim issuerClaim = issuerClaimSet[0];
        if (issuerClaim.ClaimType != ClaimTypes.Thumbprint)
            return false;
        if (issuerClaim.Resource == null) return false;
        byte[] claimThumbprint = (byte[])issuerClaim.Resource;
        // It is assumed that stsB_Certificate is a variable of type
        // X509Certificate2 that is initialized with the Certificate of
        // STS-B.
        X509Certificate2 stsB_Certificate = GetStsBCertificate();
        byte[] certThumbprint = stsB_Certificate.GetCertHash();
        if (claimThumbprint.Length != certThumbprint.Length)
            return false;
        for (int i = 0; i < claimThumbprint.Length; i++)
        {
            if (claimThumbprint[i] != certThumbprint[i]) return false;
        }
        return true;
    }
Public Class myServiceAuthorizationManager
    Inherits ServiceAuthorizationManager

    ' Override the CheckAccess method to enforce access control requirements.
    Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
        Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
        If authContext.ClaimSets Is Nothing Then
            Return False
        End If

        If authContext.ClaimSets.Count <> 1 Then
            Return False
        End If

        Dim myClaimSet = authContext.ClaimSets(0)
        If Not IssuedBySTS_B(myClaimSet) Then
            Return False
        End If
        If myClaimSet.Count <> 1 Then
            Return False
        End If
        Dim myClaim = myClaimSet(0)
        If myClaim.ClaimType = "http://www.tmpuri.org:accessAuthorized" Then
            Dim resource = TryCast(myClaim.Resource, String)
            If resource Is Nothing Then
                Return False
            End If
            If resource <> "true" Then
                Return False
            End If
            Return True
        Else
            Return False
        End If
    End Function

    ' This helper method checks whether SAML Token was issued by STS-B.     
    ' It compares the Thumbprint Claim of the Issuer against the 
    ' Certificate of STS-B. 
    Private Function IssuedBySTS_B(ByVal myClaimSet As ClaimSet) As Boolean
        Dim issuerClaimSet = myClaimSet.Issuer
        If issuerClaimSet Is Nothing Then
            Return False
        End If
        If issuerClaimSet.Count <> 1 Then
            Return False
        End If
        Dim issuerClaim = issuerClaimSet(0)
        If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
            Return False
        End If
        If issuerClaim.Resource Is Nothing Then
            Return False
        End If
        Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
        ' It is assumed that stsB_Certificate is a variable of type 
        ' X509Certificate2 that is initialized with the Certificate of 
        ' STS-B.
        Dim stsB_Certificate = GetStsBCertificate()
        Dim certThumbprint() = stsB_Certificate.GetCertHash()
        If claimThumbprint.Length <> certThumbprint.Length Then
            Return False
        End If
        For i = 0 To claimThumbprint.Length - 1
            If claimThumbprint(i) <> certThumbprint(i) Then
                Return False
            End If
        Next i
        Return True
    End Function

STS B

Ilustrasi berikut menunjukkan STS B. Seperti yang dinyatakan sebelumnya, layanan token keamanan (STS) juga merupakan layanan Web dan dapat memiliki titik akhir, kebijakan, dan sebagainya yang terkait.

Diagram showing security token service B.

STS B mengekspos satu titik akhir, yang disebut STSEndpoint yang dapat digunakan untuk meminta token keamanan. Secara khusus, STS B mengeluarkan token SAML dengan klaim accessAuthorized, yang dapat disajikan di situs layanan MyService untuk mengakses layanan. Namun, STS B mengharuskan pengguna untuk menunjukkan token SAML valid yang dikeluarkan oleh STS A yang berisi klaim userAuthenticated. Operasi ini secara deklaratif ditentukan dalam konfigurasi STS.

<system.serviceModel>  
  <services>  
    <service type="FederationSample.STS_B" behaviorConfiguration=  
     "STS-B_Behavior">  
    <endpoint address=""  
              binding="wsFederationHttpBinding"  
              bindingConfiguration='STS-B_Binding'  
      contract="FederationSample.ISts" />  
    </service>  
  </services>  
  <bindings>  
    <wsFederationHttpBinding>  
    <!-- This is the binding used by STS-B. It redirects clients to   
         STS-A. -->  
      <binding name='STS-B_Binding'>  
        <security mode='Message'>  
          <message issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">  
          <issuer address='http://localhost/FederationSample/STS-A/STS.svc' />  
          <issuerMetadata address='http://localhost/FederationSample/STS-A/STS.svc/mex'/>  
          <requiredClaimTypes>  
            <add claimType='http://tempuri.org:userAuthenticated'/>  
          </requiredClaimTypes>  
          </message>  
        </security>  
    </binding>  
   </wsFederationHttpBinding>  
  </bindings>  
  <behaviors>  
  <behavior name='STS-B_Behavior'>  
    <serviceAuthorization   operationRequirementType='FederationSample.STS_B_OperationRequirement, STS_B' />  
    <serviceCredentials>  
      <serviceCertificate findValue='CN=FederationSample.com'  
      x509FindType='FindBySubjectDistinguishedName'  
       storeLocation='LocalMachine'  
       storeName='My' />  
     </serviceCredentials>  
   </behavior>  
  </behaviors>  
</system.serviceModel>  

Catatan

Sekali lagi, klaim userAuthenticated adalah jenis klaim yang diperlukan oleh STS B. Nama yang sepenuhnya memenuhi syarat dari jenis klaim ini adalah http://tempuri.org:userAuthenticated (bersama dengan namespace terkait), yang digunakan dalam file konfigurasi STS. Nilai klaim ini menunjukkan adanya klaim ini dan diasumsikan ditetapkan ke true oleh STS A.

Di runtime, kelas STS_B_OperationRequirement menerapkan kebijakan ini, yang diterapkan sebagai bagian dari STS B.

public class STS_B_AuthorizationManager : ServiceAuthorizationManager
{

    // Override AccessCheck to enforce access control requirements.
    public override bool CheckAccess(OperationContext operationContext)
    {
        AuthorizationContext authContext =
        operationContext.ServiceSecurityContext.AuthorizationContext;
        if (authContext.ClaimSets == null) return false;
        if (authContext.ClaimSets.Count != 1) return false;
        ClaimSet myClaimSet = authContext.ClaimSets[0];
        if (!IssuedBySTS_A(myClaimSet)) return false;
        if (myClaimSet.Count != 1) return false;
        Claim myClaim = myClaimSet[0];
        if (myClaim.ClaimType == "http://www.tmpuri.org:userAuthenticated")
        {
            string resource = myClaim.Resource as string;
            if (resource == null) return false;
            if (resource != "true") return false;
            return true;
        }
        else
        {
            return false;
        }
    }

    // This helper method checks whether SAML Token was issued by STS-A.
    // It compares the Thumbprint Claim of the Issuer against the
    // Certificate of STS-A.
    private bool IssuedBySTS_A(ClaimSet myClaimSet)
    {
        ClaimSet issuerClaimSet = myClaimSet.Issuer;
        if (issuerClaimSet == null) return false;
        if (issuerClaimSet.Count != 1) return false;
        Claim issuerClaim = issuerClaimSet[0];
        if (issuerClaim.ClaimType != ClaimTypes.Thumbprint) return false;
        if (issuerClaim.Resource == null) return false;
        byte[] claimThumbprint = (byte[])issuerClaim.Resource;
        // It is assumed that stsA_Certificate is a variable of type X509Certificate2
        // that is initialized with the Certificate of STS-A.
        X509Certificate2 stsA_Certificate = GetStsACertificate();

        byte[] certThumbprint = stsA_Certificate.GetCertHash();
        if (claimThumbprint.Length != certThumbprint.Length) return false;
        for (int i = 0; i < claimThumbprint.Length; i++)
        {
            if (claimThumbprint[i] != certThumbprint[i]) return false;
        }
        return true;
    }
Public Class STS_B_AuthorizationManager
    Inherits ServiceAuthorizationManager

    ' Override AccessCheck to enforce access control requirements.
    Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
        Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
        If authContext.ClaimSets Is Nothing Then
            Return False
        End If
        If authContext.ClaimSets.Count <> 1 Then
            Return False
        End If
        Dim myClaimSet = authContext.ClaimSets(0)
        If Not IssuedBySTS_A(myClaimSet) Then
            Return False
        End If
        If myClaimSet.Count <> 1 Then
            Return False
        End If
        Dim myClaim = myClaimSet(0)
        If myClaim.ClaimType = "http://www.tmpuri.org:userAuthenticated" Then
            Dim resource = TryCast(myClaim.Resource, String)
            If resource Is Nothing Then
                Return False
            End If
            If resource <> "true" Then
                Return False
            End If
            Return True
        Else
            Return False
        End If
    End Function

    ' This helper method checks whether SAML Token was issued by STS-A. 
    ' It compares the Thumbprint Claim of the Issuer against the 
    ' Certificate of STS-A.
    Private Function IssuedBySTS_A(ByVal myClaimSet As ClaimSet) As Boolean
        Dim issuerClaimSet = myClaimSet.Issuer
        If issuerClaimSet Is Nothing Then
            Return False
        End If
        If issuerClaimSet.Count <> 1 Then
            Return False
        End If
        Dim issuerClaim = issuerClaimSet(0)
        If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
            Return False
        End If
        If issuerClaim.Resource Is Nothing Then
            Return False
        End If
        Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
        ' It is assumed that stsA_Certificate is a variable of type X509Certificate2
        ' that is initialized with the Certificate of STS-A.
        Dim stsA_Certificate = GetStsACertificate()

        Dim certThumbprint() = stsA_Certificate.GetCertHash()
        If claimThumbprint.Length <> certThumbprint.Length Then
            Return False
        End If
        For i = 0 To claimThumbprint.Length - 1
            If claimThumbprint(i) <> certThumbprint(i) Then
                Return False
            End If
        Next i
        Return True
    End Function

Jika pemeriksaan akses selesai, STS B mengeluarkan token SAML dengan klaim accessAuthorized.

// Create the list of SAML Attributes.
List<SamlAttribute> samlAttributes = new List<SamlAttribute>();

// Add the accessAuthorized claim.
List<string> strList = new List<string>();
strList.Add("true");
samlAttributes.Add(new SamlAttribute("http://www.tmpuri.org",
"accessAuthorized",
strList));

// Create the SAML token with the accessAuthorized claim. It is assumed that
// the method CreateSamlToken() is implemented as part of STS-B.
SamlSecurityToken samlToken = CreateSamlToken(
    proofToken,
    issuerToken,
    samlConditions,
    samlSubjectNameFormat,
    samlSubjectEmailAddress,
    samlAttributes);
' Create the list of SAML Attributes.
Dim samlAttributes As New List(Of SamlAttribute)()

' Add the accessAuthorized claim.
Dim strList As New List(Of String)()
strList.Add("true")
samlAttributes.Add(New SamlAttribute("http://www.tmpuri.org", "accessAuthorized", strList))

' Create the SAML token with the accessAuthorized claim. It is assumed that 
' the method CreateSamlToken() is implemented as part of STS-B.
Dim samlToken = CreateSamlToken(proofToken, _
                                issuerToken, _
                                samlConditions, _
                                samlSubjectNameFormat, _
                                samlSubjectEmailAddress, _
                                samlAttributes)

STS A

Ilustrasi berikut menunjukkan STS A.

Federation

Mirip dengan STS B, STS A juga merupakan layanan Web yang mengeluarkan token keamanan dan mengekspos satu titik akhir untuk tujuan ini. Namun, operasi ini menggunakan pengikatan yang berbeda (wsHttpBinding) dan mengharuskan pengguna untuk menunjukkan CardSpace yang valid dengan klaim emailAddress. Sebagai tanggapan, operasi ini mengeluarkan token SAML dengan klaim userAuthenticated. Operasi ini secara deklaratif ditentukan dalam konfigurasi layanan.

<system.serviceModel>  
  <services>  
    <service type="FederationSample.STS_A" behaviorConfiguration="STS-A_Behavior">  
      <endpoint address=""  
                binding="wsHttpBinding"  
                bindingConfiguration="STS-A_Binding"  
                contract="FederationSample.ISts">  
       <identity>  
       <certificateReference findValue="CN=FederationSample.com"
                       x509FindType="FindBySubjectDistinguishedName"  
                       storeLocation="LocalMachine"
                       storeName="My" />  
       </identity>  
    </endpoint>  
  </service>  
</services>  
  
<bindings>  
  <wsHttpBinding>  
  <!-- This is the binding used by STS-A. It requires users to present  
   a CardSpace. -->  
    <binding name='STS-A_Binding'>  
      <security mode='Message'>  
        <message clientCredentialType="CardSpace" />  
      </security>  
    </binding>  
  </wsHttpBinding>  
</bindings>  
  
<behaviors>  
  <behavior name='STS-A_Behavior'>  
    <serviceAuthorization operationRequirementType=  
     "FederationSample.STS_A_OperationRequirement, STS_A" />  
      <serviceCredentials>  
  <serviceCertificate findValue="CN=FederationSample.com"  
                     x509FindType='FindBySubjectDistinguishedName'  
                     storeLocation='LocalMachine'  
                     storeName='My' />  
      </serviceCredentials>  
    </behavior>  
  </behaviors>  
</system.serviceModel>  

Saat dijalankan, kelas STS_A_OperationRequirement menerapkan kebijakan ini, yang diterapkan sebagai bagian dari STS A.


public class STS_A_AuthorizationManager : ServiceAuthorizationManager
{
    // Override AccessCheck to enforce access control requirements.
    public override bool CheckAccess(OperationContext operationContext)
    {
        AuthorizationContext authContext =
        operationContext.ServiceSecurityContext.AuthorizationContext;
        if (authContext.ClaimSets == null) return false;
        if (authContext.ClaimSets.Count != 1) return false;
        ClaimSet myClaimSet = authContext.ClaimSets[0];
        if (myClaimSet.Count != 1) return false;
        Claim myClaim = myClaimSet[0];
        if ((myClaim.ClaimType ==
        @"http://schemas.microsoft.com/ws/2005/05/identity/claims:EmailAddress") &&
        (myClaim.Right == Rights.PossessProperty))
        {
            string emailAddress = myClaim.Resource as string;
            if (emailAddress == null) return false;
            if (!IsValidEmailAddress(emailAddress)) return false;
            return true;
        }
        else
        {
            return false;
        }
    }

    // This helper method performs a rudimentary check for whether
    //a given email is valid.
    private static bool IsValidEmailAddress(string emailAddress)
    {
        string[] splitEmail = emailAddress.Split('@');
        if (splitEmail.Length != 2) return false;
        if (!splitEmail[1].Contains(".")) return false;
        return true;
    }
}
Public Class STS_A_AuthorizationManager
    Inherits ServiceAuthorizationManager

    ' Override AccessCheck to enforce access control requirements.
    Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
        Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
        If authContext.ClaimSets Is Nothing Then
            Return False
        End If
        If authContext.ClaimSets.Count <> 1 Then
            Return False
        End If
        Dim myClaimSet = authContext.ClaimSets(0)
        If myClaimSet.Count <> 1 Then
            Return False
        End If
        Dim myClaim = myClaimSet(0)
        If myClaim.ClaimType = "http://schemas.microsoft.com/ws/2005/05/identity/claims:EmailAddress" AndAlso myClaim.Right = Rights.PossessProperty Then
            Dim emailAddress = TryCast(myClaim.Resource, String)
            If emailAddress Is Nothing Then
                Return False
            End If
            If Not IsValidEmailAddress(emailAddress) Then
                Return False
            End If
            Return True
        Else
            Return False
        End If
    End Function

    ' This helper method performs a rudimentary check for whether 
    'a given email is valid.
    Private Shared Function IsValidEmailAddress(ByVal emailAddress As String) As Boolean
        Dim splitEmail() = emailAddress.Split("@"c)
        If splitEmail.Length <> 2 Then
            Return False
        End If
        If Not splitEmail(1).Contains(".") Then
            Return False
        End If
        Return True
    End Function
End Class

Jika aksesnya adalah true, STS A mengeluarkan token SAML dengan klaim userAuthenticated.

// Create the list of SAML Attributes.
List<SamlAttribute> samlAttributes = new List<SamlAttribute>();
// Add the userAuthenticated claim.
List<string> strList = new List<string>();
strList.Add("true");
SamlAttribute mySamlAttribute = new SamlAttribute("http://www.tmpuri.org",
     "userAuthenticated", strList);
samlAttributes.Add(mySamlAttribute);
// Create the SAML token with the userAuthenticated claim. It is assumed that
// the method CreateSamlToken() is implemented as part of STS-A.
SamlSecurityToken samlToken = CreateSamlToken(
    proofToken,
    issuerToken,
    samlConditions,
    samlSubjectNameFormat,
    samlSubjectEmailAddress,
    samlAttributes);
' Create the list of SAML Attributes.
Dim samlAttributes As New List(Of SamlAttribute)()
' Add the userAuthenticated claim.
Dim strList As New List(Of String)()
strList.Add("true")
Dim mySamlAttribute As New SamlAttribute("http://www.tmpuri.org", _
                                         "userAuthenticated", _
                                         strList)
samlAttributes.Add(mySamlAttribute)
' Create the SAML token with the userAuthenticated claim. It is assumed that 
' the method CreateSamlToken() is implemented as part of STS-A.
Dim samlToken = CreateSamlToken(proofToken, issuerToken, samlConditions, _
                                samlSubjectNameFormat, _
                                samlSubjectEmailAddress, _
                                samlAttributes)

Klien di Organisasi A

Ilustrasi berikut menunjukkan klien di organisasi A, bersama dengan langkah-langkah yang terlibat dalam membuat panggilan layanan MyService. Komponen fungsional lainnya juga disertakan untuk kelengkapan.

Diagram showing the steps in a MyService service call.

Ringkasan

Keamanan gabungan memberikan pembagian tanggung jawab yang mulus dan membantu membangun arsitektur layanan yang aman dan dapat diskalakan. Sebagai platform untuk membangun dan menyebarkan aplikasi terdistribusi, WCF menyediakan dukungan native untuk menerapkan keamanan federasi.

Lihat juga