Procedura: Confrontare le attestazioni

L'infrastruttura del modello di identità in Windows Communication Foundation (WCF) viene usata per eseguire il controllo delle autorizzazioni. Di conseguenza, un'attività comune consiste nel confrontare le attestazioni nel contesto di autorizzazione con le attestazioni necessarie per eseguire l'azione richiesta o accedere alla risorsa richiesta. Questo argomento descrive come confrontare le attestazioni, inclusi i tipi di attestazioni predefiniti e personalizzati. Per altre informazioni sull'infrastruttura del modello di identità, vedere Gestione delle attestazioni e dell'autorizzazione con il modello di identità.

Il confronto delle attestazioni comporta il confronto tra le tre parti di un'attestazione (tipo, diritto e risorsa) con le stesse parti di un'altra attestazione per verificare se sono uguali. Vedi l'esempio seguente.

Claim c1 = Claim.CreateNameClaim("someone");
Claim c2 = Claim.CreateNameClaim("someone");
Dim c1 As Claim = Claim.CreateNameClaim("someone")
Dim c2 As Claim = Claim.CreateNameClaim("someone")

Entrambe le attestazioni hanno un tipo di Name attestazione, un diritto di PossessProperty, e una risorsa della stringa "qualcuno". Poiché tutte e tre le parti dell'attestazione sono uguali, le attestazioni stesse sono uguali.

I tipi di attestazione predefiniti vengono confrontati utilizzando il metodo Equals. Il codice di confronto specifico della richiesta viene usato se necessario. Ad esempio, data le due attestazioni UPN (User Principal Name) seguenti, il codice di confronto nel Equals metodo restituisce true, presupponendo che example\someone identifichi lo stesso utente di dominio di someone@example.com.

Claim c1 = Claim.CreateUpnClaim("someone@example.com");
Claim c2 = Claim.CreateUpnClaim("example\\someone");
Dim c1 As Claim = Claim.CreateUpnClaim("someone@example.com")
Dim c2 As Claim = Claim.CreateUpnClaim("example\someone")

È possibile confrontare anche i tipi di claim personalizzati utilizzando il metodo Equals. Tuttavia, nei casi in cui il tipo restituito dalla proprietà Resource dell'attestazione è diverso da un tipo primitivo, Equals restituisce true solo se i valori restituiti dalle proprietà Resource sono uguali secondo il metodo Equals. Nei casi in cui ciò non è appropriato, il tipo personalizzato restituito dalla proprietà Resource dovrebbe sovrascrivere le Equals e le GetHashCode per eseguire qualsiasi elaborazione personalizzata necessaria.

Confronto delle attestazioni predefinite

  1. Dati due istanze della classe Claim, utilizzare Equals per eseguire il confronto, come illustrato nel codice seguente.

    public bool CompareTwoClaims(Claim c1, Claim c2)
    {
        return c1.Equals(c2);
    }
    
    Public Function CompareTwoClaims(ByVal c1 As Claim, ByVal c2 As Claim) As Boolean
        Return c1.Equals(c2)
    End Function
    

Confronto di attestazioni personalizzate con tipi di risorse primitive

  1. Per le attestazioni personalizzate con tipi di risorse primitive, è possibile eseguire il confronto come per le attestazioni predefinite, come illustrato nel codice seguente.

    public bool CompareTwoClaims(Claim c1, Claim c2)
    {
        return c1.Equals(c2);
    }
    
    Public Function CompareTwoClaims(ByVal c1 As Claim, _
    ByVal c2 As Claim) As Boolean
        Return c1.Equals(c2)
    
    End Function
    
  2. Per le attestazioni personalizzate con tipi di risorse basati su struttura o classe, il tipo di risorsa deve sovrascrivere il metodo Equals.

  3. Controllare prima di tutto se il obj parametro è nulle, in caso affermativo, restituire false.

    if (obj == null) return false;
    
    If obj Is Nothing Then
        Return False
    
  4. Chiama ReferenceEquals e passa this e obj come parametri. Se restituisce true, allora restituisci true.

    if (ReferenceEquals(this, obj)) return true;
    
    If ReferenceEquals(Me, obj) Then
        Return True
    
  5. Tentare quindi di assegnare obj a una variabile locale del tipo di classe. Se l'operazione ha esito negativo, il riferimento è null. In questi casi, restituire false.

  6. Eseguire il confronto personalizzato necessario per confrontare correttamente l'attestazione corrente con l'attestazione specificata.

Esempio

L'esempio seguente mostra un confronto di attestazioni personalizzate in cui la risorsa di attestazione è di un tipo non primitivo.

using System;
using System.IdentityModel.Claims;

namespace Samples
{
    public sealed class MyResourceType
    {
        // private members
        private string text;
        private int number;

        // Constructors
        public MyResourceType()
        {
        }

        public MyResourceType(string text, int number)
        {
            this.text = text;
            this.number = number;
        }

        // Public properties
        public string Text { get { return this.text; } }
        public int Number { get { return this.number; } }

        // Override Object.Equals to perform specific comparison
        public override bool Equals(Object obj)
        {
            // If the object we're being asked to compare ourselves to is null
            // then return false
            if (obj == null)
                return false;

            // If the object we're being asked to compare ourselves to is us
            // then return true
            if (ReferenceEquals(this, obj))
                return true;

            // Try to convert the object we're being asked to compare ourselves to
            // into an instance of MyResourceType
            MyResourceType rhs = obj as MyResourceType;

            // If the object we're being asked to compare ourselves to
            // isn't an instance of MyResourceType then return false
            if (rhs == null)
                return false;

            // Return true if our members are the same as those of the object
            // we're being asked to compare ourselves to. Otherwise return false
            return (this.text == rhs.text && this.number == rhs.number);
        }

        public override int GetHashCode()
        {
            return (this.text.GetHashCode() ^ this.number.GetHashCode());
        }
    }

    class Program
    {
        public static void Main()
        {
            // Create two claims
            Claim c1 = new Claim("http://example.org/claims/mycustomclaim",
                new MyResourceType("Martin", 38), Rights.PossessProperty);
            Claim c2 = new Claim("http://example.org/claims/mycustomclaim",
                new MyResourceType("Martin", 38), Rights.PossessProperty);

            // Compare the claims
            if (c1.Equals(c2))
                Console.WriteLine("Claims are equal");
            else
                Console.WriteLine("Claims are not equal");
        }
    }
}
Imports System.IdentityModel.Claims
Imports System.Security.Permissions

NotInheritable Public Class MyResourceType
    ' private members
    Private textValue As String
    Private numberValue As Integer


    ' Constructors
    Public Sub New()

    End Sub

    Public Sub New(ByVal textVal As String, ByVal numberValue As Integer)
        Me.textValue = textVal
        Me.numberValue = numberValue

    End Sub

    ' Public properties

    Public ReadOnly Property Text() As String
        Get
            Return Me.textValue
        End Get
    End Property

    Public ReadOnly Property Number() As Integer
        Get
            Return Me.numberValue
        End Get
    End Property
    ' Override Object.Equals to perform a specific comparison.
    Public Overrides Function Equals(ByVal obj As [Object]) As Boolean
        ' If the object being compared to is null then return false.
        If obj Is Nothing Then
            Return False
        End If
        ' If the object we are being asked to compare ourselves to is us
        ' then return true.
        If ReferenceEquals(Me, obj) Then
            Return True
        End If
        ' Try to convert the object we are being asked to compare ourselves to
        ' into an instance of MyResourceType.
        Dim rhs As MyResourceType = CType(obj, MyResourceType)

        ' If the object being compared to is not an instance of 
        ' MyResourceType then return false.
        If rhs Is Nothing Then
            Return False
        End If
        ' Return true if members are the same as those of the object
        ' being asked to compare to; otherwise, return false.
        Return Me.textValue = rhs.textValue AndAlso Me.numberValue = rhs.numberValue

    End Function

    Public Overrides Function GetHashCode() As Integer
        Return Me.textValue.GetHashCode() ^ Me.numberValue.GetHashCode()

    End Function
End Class
Class Program

    Public Shared Sub Main()
        ' Create two claims.
        Dim c1 As New Claim("http://example.org/claims/mycustomclaim", _
           New MyResourceType("Martin", 38), Rights.PossessProperty)
        Dim c2 As New Claim("http://example.org/claims/mycustomclaim", _
           New MyResourceType("Martin", 38), Rights.PossessProperty)

        ' Compare the claims.
        If c1.Equals(c2) Then
            Console.WriteLine("Claims are equal")
        Else
            Console.WriteLine("Claims are not equal")
        End If

    End Sub
End Class

Vedere anche