Compartir a través de


Cómo: Comparar notificaciones

La infraestructura del modelo de identidad en Windows Communication Foundation (WCF) se utiliza para realizar la comprobación de autorización. Como tal, una tarea común es comparar las notificaciones en el contexto de autorización con las notificaciones necesarias para realizar la acción solicitada o tener acceso al recurso solicitado. En este tema se describe cómo comparar las notificaciones, incluidos los tipos de notificación integrados y personalizados. Para obtener más información sobre la infraestructura del modelo de identidad, vea Administración de notificaciones y autorización con el modelo de identidad.

La comparación de notificaciones implica la comparación de las tres partes de una notificación (tipo, derecho y recurso) con las mismas partes de otra notificación para ver si son iguales. Vea el ejemplo siguiente.

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

Ambas notificaciones tienen un tipo de notificación Name, un derecho PossessProperty y un recurso con la cadena "someone". Como las tres partes de la notificación son iguales, las notificaciones en sí mismas también lo son.

Los tipos de notificación integrados se comparan mediante el método Equals. Se utiliza el código de la comparación específico de la notificación allí donde sea necesario. Por ejemplo, dadas las siguientes dos notificaciones del nombre principal del usuario (UPN):

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

el código de la comparación en el método Equals devuelve true, al suponer que example\someone identifica el mismo usuario de dominio que "someone@example.com."

Los tipos de notificación personalizados también se pueden comparar con el método Equals. Sin embargo, en los casos en que el tipo devuelto por la propiedad Resource de la notificación es distinto a un tipo primitivo, Equals solo devuelve true si los valores devueltos por las propiedades Resource son iguales de acuerdo con el método Equals. En los casos en que esto no sea adecuado, el tipo personalizado devuelto por la propiedad Resource debería invalidar los métodos Equals y GetHashCode para realizar el procesamiento personalizado que sea necesario.

Comparación de notificaciones integradas

  1. Dadas dos instancias de la clase Claim, utilice Equals para realizar la comparación, tal y como se muestra en el código siguiente.

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

Comparación de las notificaciones personalizadas con los tipos de recursos primitivos

  1. En el caso de las notificaciones personalizadas con tipos de recursos primitivos, se puede realizar la comparación para las notificaciones integradas, tal y como se muestra en el código siguiente.

    Public Function CompareTwoClaims(ByVal c1 As Claim, _
    ByVal c2 As Claim) As Boolean 
        Return c1.Equals(c2)
    
    End Function         
    
    public bool CompareTwoClaims(Claim c1, Claim c2)
    {
        return c1.Equals(c2);
    }
    
  2. En el caso de las notificaciones con tipos de recursos basados en la estructura o la clase, el tipo de recurso debería invalidar el método Equals.

  3. Primero compruebe si el parámetro obj es null y, en ese caso, devuelva false.

    If obj Is Nothing Then
        Return False
    
    if (obj == null) return false;
    
  4. A continuación, llame a ReferenceEquals y pase this y obj como parámetros. Si devuelve true, devuelva true.

    If ReferenceEquals(Me, obj) Then
        Return True
    
    if (ReferenceEquals(this, obj)) return true;
    
  5. Luego intente asignar obj a una variable local del tipo de clase. Si se produce un error, la referencia será null. En tales casos, devuelva false.

  6. Realice la comparación personalizada necesaria para comparar correctamente la notificación actual con la notificación proporcionada.

Ejemplo

El ejemplo siguiente muestra una comparación de notificaciones personalizadas donde el recurso de la notificación es un tipo no primitivo.

Imports System
Imports System.IdentityModel.Claims
Imports System.Security.Permissions

<assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution := True)>
NotInheritable Public Class MyResourceType
    ' private members
    Private textValue As String
    Private numberValue As Integer
    
    
    ' Constructors
    Public Sub New() 
    
    End Sub 'New
    
    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 
using System;
using System.IdentityModel.Claims;
using System.Security.Permissions;
[assembly: SecurityPermission(
   SecurityAction.RequestMinimum, Execution = true)]
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 specfic 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");
        }
    }
}

Vea también

Tareas

Cómo crear una notificación personalizada

Conceptos

Administración de notificaciones y autorización con el modelo de identidad