Dela via


Federation

Det här avsnittet innehåller en kort översikt över begreppet federerad säkerhet. Den beskriver också WCF-stöd (Windows Communication Foundation) för distribution av federerade säkerhetsarkitekturer. Ett exempelprogram som visar federation finns i Federationsexempel.

Definition av federerad säkerhet

Federerad säkerhet möjliggör en ren separation mellan den tjänst som en klient har åtkomst till och de associerade procedurerna för autentisering och auktorisering. Federerad säkerhet möjliggör också samarbete mellan flera system, nätverk och organisationer i olika förtroendesfärer.

WCF ger stöd för att skapa och distribuera distribuerade system som använder federerad säkerhet.

Element i en federerad säkerhetsarkitektur

Den federerade säkerhetsarkitekturen har tre viktiga element, enligt beskrivningen i följande tabell.

Element Description
Domän/sfär En enda enhet för säkerhetsadministration eller förtroende. En typisk domän kan innehålla en enda organisation.
Federation En samling domäner som har upprättat förtroende. Förtroendenivån kan variera, men omfattar vanligtvis autentisering och nästan alltid auktorisering. En typisk federation kan innehålla ett antal organisationer som har upprättat förtroende för delad åtkomst till en uppsättning resurser.
Security Token Service (STS) En webbtjänst som utfärdar säkerhetstoken. Den gör alltså påståenden baserade på bevis som den litar på, till den som litar på den. Detta utgör grunden för förtroendeutjämning mellan domäner.

Exempel på ett scenario

Följande bild visar ett exempel på federerad säkerhet:

Diagram showing a typical federated security scenario.

Det här scenariot omfattar två organisationer: A och B. Organisation B har en webbresurs (en webbtjänst) som vissa användare i organisationen A tycker är värdefulla.

Kommentar

I det här avsnittet används termerna resurs, tjänst och webbtjänst på ett utbytbart sätt.

Vanligtvis kräver organisation B att en användare från organisationen A tillhandahåller någon giltig form av autentisering innan de får åtkomst till tjänsten. Dessutom kan organisationen kräva att användaren har behörighet att komma åt den aktuella resursen. Ett sätt att åtgärda det här problemet och göra det möjligt för användare i organisation A att komma åt resursen i organisation B är följande:

  • Användare från organisationen A registrerar sina autentiseringsuppgifter (ett användarnamn och lösenord) med organisation B.

  • Under resursåtkomsten presenterar användare från organisationen A sina autentiseringsuppgifter för organisation B och autentiseras innan de får åtkomst till resursen.

Den här metoden har tre viktiga nackdelar:

  • Organisation B måste hantera autentiseringsuppgifterna för användare från organisation A förutom att hantera autentiseringsuppgifterna för sina lokala användare.

  • Användare i organisationen Ett behov av att behålla ytterligare en uppsättning autentiseringsuppgifter (dvs. komma ihåg ytterligare ett användarnamn och lösenord) förutom de autentiseringsuppgifter som de normalt använder för att få åtkomst till resurser inom organisation A. Detta uppmuntrar vanligtvis till att använda samma användarnamn och lösenord på flera tjänstwebbplatser, vilket är en svag säkerhetsåtgärd.

  • Arkitekturen skalas inte eftersom fler organisationer uppfattar resursen i organisation B som av något värde.

En alternativ metod, som tar upp de tidigare nämnda nackdelarna, är att använda federerad säkerhet. I den här metoden etablerar organisationer A och B en förtroenderelation och använder Security Token Service (STS) för att möjliggöra utjämning av det etablerade förtroendet.

I en federerad säkerhetsarkitektur vet användare från organisationen A att om de vill komma åt webbtjänsten i organisation B måste de presentera en giltig säkerhetstoken från STS i organisationen B, som autentiserar och auktoriserar deras åtkomst till den specifika tjänsten.

När de kontaktar STS B får användarna ytterligare en indirekt nivå från principen som är associerad med STS. De måste presentera en giltig säkerhetstoken från STS A (dvs. klientförtroendesfären) innan STS B kan utfärda en säkerhetstoken till dem. Detta är en följd av den förtroenderelation som upprättats mellan de två organisationerna och innebär att organisation B inte behöver hantera identiteter för användare från organisation A. I praktiken har STS B vanligtvis null issuerAddress och issuerMetadataAddress. Mer information finns i Så här konfigurerar du en lokal utfärdare. I så fall konsulterar klienten en lokal princip för att hitta STS A. Den här konfigurationen kallas för hemsfärfederation och skalas bättre eftersom STS B inte behöver underhålla information om STS A.

Användarna kontaktar sedan STS i organisation A och hämtar en säkerhetstoken genom att presentera autentiseringsuppgifter som de normalt använder för att få åtkomst till andra resurser inom organisation A. Detta minskar också problemet med att användare måste underhålla flera uppsättningar autentiseringsuppgifter eller använda samma uppsättning autentiseringsuppgifter på flera tjänstplatser.

När användarna får en säkerhetstoken från STS A presenterar de token för STS B. Organisation B fortsätter att auktorisera användarnas begäranden och utfärdar en säkerhetstoken till användarna från sin egen uppsättning säkerhetstoken. Användarna kan sedan presentera sin token för resursen i organisation B och få åtkomst till tjänsten.

Stöd för federerad säkerhet i WCF

WCF ger nyckelfärdigt stöd för att distribuera federerade säkerhetsarkitekturer via wsFederationHttpBinding>.<

WsFederationHttpBinding-elementet ><ger en säker, tillförlitlig, driftskompatibel bindning som innebär att HTTP används som den underliggande transportmekanismen för kommunikationsstil för begärandesvar och använder text och XML som trådformat för kodning.

Användningen av <wsFederationHttpBinding> i ett federerat säkerhetsscenario kan frikopplas till två logiskt oberoende faser, enligt beskrivningen i följande avsnitt.

Fas 1: Designfas

Under designfasen använder klienten verktyget ServiceModel Metadata Utility (Svcutil.exe) för att läsa principen som tjänstslutpunkten exponerar och för att samla in tjänstens autentiserings- och auktoriseringskrav. Lämpliga proxyservrar skapas för att skapa följande federerade säkerhetskommunikationsmönster på klienten:

  • Hämta en säkerhetstoken från STS i klientförtroendesfären.

  • Presentera token för STS i tjänstens förtroendesfär.

  • Hämta en säkerhetstoken från STS i tjänstens förtroendesfär.

  • Presentera token för tjänsten för att få åtkomst till tjänsten.

Fas 2: Körningsfas

Under körningsfasen instansierar klienten ett objekt i WCF-klientklassen och anropar med hjälp av WCF-klienten. Det underliggande ramverket för WCF hanterar de tidigare nämnda stegen i det federerade säkerhetskommunikationsmönstret och gör det möjligt för klienten att sömlöst använda tjänsten.

Exempelimplementering med WCF

Följande bild visar en exempelimplementering för en federerad säkerhetsarkitektur med inbyggt stöd från WCF.

Diagram showing a sample Federation security implementation.

Exempel på MyService

Tjänsten MyService exponerar en enskild slutpunkt via MyServiceEndpoint. Följande bild visar adressen, bindningen och kontraktet som är associerat med slutpunkten.

Diagram showing the MyServiceEndpoint details.

Tjänstslutpunkten MyServiceEndpoint använder <wsFederationHttpBinding> och kräver en giltig SAML-token (Security Assertions Markup Language) med ett accessAuthorized anspråk utfärdat av STS B. Detta anges deklarativt i tjänstkonfigurationen.

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

Kommentar

En subtil punkt bör noteras om de anspråk som krävs av MyService. Den andra bilden anger att kräver MyService en SAML-token med anspråket accessAuthorized . För att vara mer exakt anger detta den anspråkstyp som MyService krävs. Det fullständigt kvalificerade namnet på den här anspråkstypen är http://tempuri.org:accessAuthorized (tillsammans med det associerade namnområdet), som används i tjänstkonfigurationsfilen. Värdet för det här anspråket anger förekomsten av det här anspråket och antas vara inställt på true av STS B.

Vid körning framtvingas den här principen av klassen MyServiceOperationRequirement som implementeras som en del av 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

Följande bild visar STS B. Som tidigare nämnts är en säkerhetstokentjänst (STS) också en webbtjänst och kan ha tillhörande slutpunkter, principer och så vidare.

Diagram showing security token service B.

STS B exponerar en enda slutpunkt, kallad STSEndpoint som kan användas för att begära säkerhetstoken. Mer specifikt utfärdar STS B SAML-token med anspråket accessAuthorized , som kan visas på tjänstwebbplatsen MyService för åtkomst till tjänsten. STS B kräver dock att användare presenterar en giltig SAML-token utfärdad av STS A som innehåller anspråket userAuthenticated . Detta anges deklarativt i STS-konfigurationen.

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

Kommentar

Återigen är anspråket userAuthenticated den anspråkstyp som krävs av STS B. Det fullständigt kvalificerade namnet på den här anspråkstypen är http://tempuri.org:userAuthenticated (tillsammans med det associerade namnområdet), som används i STS-konfigurationsfilen. Värdet för det här anspråket anger förekomsten av det här anspråket och antas vara inställt på true av STS A.

Vid körning tillämpar klassen den STS_B_OperationRequirement här principen, som implementeras som en del av 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

Om åtkomstkontrollen är klar utfärdar STS B en SAML-token med anspråket 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

Följande bild visar STS A.

Federation

På samma sätt som STS B är STS A också en webbtjänst som utfärdar säkerhetstoken och exponerar en enda slutpunkt för detta ändamål. Den använder dock en annan bindning (wsHttpBinding) och kräver att användarna presenterar ett giltigt CardSpace med ett emailAddress anspråk. Som svar utfärdar den SAML-token med anspråket userAuthenticated . Detta anges deklarativt i tjänstkonfigurationen.

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

Vid körning tillämpar klassen den STS_A_OperationRequirement här principen, som implementeras som en del av 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

Om åtkomsten är trueutfärdar STS A en SAML-token med userAuthenticated anspråk.

// 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)

Klient i organisation A

Följande bild visar klienten i organisation A, tillsammans med de steg som ingår i att göra ett MyService tjänstanrop. De andra funktionella komponenterna ingår också för fullständighet.

Diagram showing the steps in a MyService service call.

Sammanfattning

Federerad säkerhet ger en ren ansvarsfördelning och hjälper till att skapa säkra, skalbara tjänstarkitekturer. WCF är en plattform för att skapa och distribuera distribuerade program och har inbyggt stöd för att implementera federerad säkerhet.

Se även