Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

How to: Compare Claims

The Identity Model infrastructure in Windows Communication Foundation (WCF) is used to perform authorization checking. As such, a common task is to compare claims in the authorization context to the claims required to perform the requested action or access the requested resource. This topic describes how to compare claims, including built-in and custom claim types. For more information about the Identity Model infrastructure, see Managing Claims and Authorization with the Identity Model.

Claim comparison involves comparing the three parts of a claim (type, right, and resource) against the same parts in another claim to see if they are equal. See the following example.

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

Both claims have a claim type of Name, a right of PossessProperty, and a resource of the string "someone". As all three parts of the claim are equal, the claims themselves are equal.

The built-in claim types are compared using the Equals method. Claim-specific comparison code is used where necessary. For example, given the following two user principal name (UPN) claims, the comparison code in the Equals method returns true, assuming example\someone identifies the same domain user as 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")

Custom claim types can also be compared using the Equals method. However, in cases where the type returned by the Resource property of the claim is something other than a primitive type, the Equals returns true only if the values returned by the Resource properties are equal according to the Equals method. In cases where this is not appropriate, the custom type returned by the Resource property should override the Equals and GetHashCode methods to perform whatever custom processing is necessary.

Comparing built-in claims

  1. Given two instances of the Claim class, use the Equals to make the comparison, as shown in the following code.

    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
    

Comparing custom claims with primitive resource types

  1. For custom claims with primitive resource types, comparison can be performed as for built-in claims, as shown in the following code.

    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. For custom claims with structure or class based resource types, the resource type should override the Equals method.

  3. First check whether the obj parameter is null, and if so, return false.

    if (obj == null) return false;
    
    If obj Is Nothing Then
     Return False
    
  4. Next call ReferenceEquals and pass this and obj as parameters. If it returns true, then return true.

    if (ReferenceEquals(this, obj)) return true;
    
    If ReferenceEquals(Me, obj) Then
     Return True
    
  5. Next attempt to assign obj to a local variable of the class type. If this fails, the reference is null. In such cases, return false.

  6. Perform the custom comparison necessary to correctly compare the current claim to the provided claim.

Example

The following example shows a comparison of custom claims where the claim resource is a non-primitive type.

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

See also

Additional resources