| File: FrameworkFork\System.ServiceModel\System\IdentityModel\Claims\ClaimComparer.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Runtime; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Security.Principal; using System.ServiceModel; namespace System.IdentityModel.Claims { internal class ClaimComparer : IEqualityComparer<Claim> { private static IEqualityComparer<Claim> s_defaultComparer; private static IEqualityComparer<Claim> s_hashComparer; private static IEqualityComparer<Claim> s_dnsComparer; private static IEqualityComparer<Claim> s_rsaComparer; private static IEqualityComparer<Claim> s_thumbprintComparer; #if SUPPORTS_WINDOWSIDENTITY || !disabled private static IEqualityComparer<Claim> s_upnComparer; #endif // SUPPORTS_WINDOWSIDENTITY private static IEqualityComparer<Claim> s_x500DistinguishedNameComparer; private IEqualityComparer _resourceComparer; private ClaimComparer(IEqualityComparer resourceComparer) { _resourceComparer = resourceComparer; } public static IEqualityComparer<Claim> GetComparer(string claimType) { if (claimType == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claimType"); if (claimType == ClaimTypes.Dns) return Dns; if (claimType == ClaimTypes.Hash) return Hash; if (claimType == ClaimTypes.Rsa) return Rsa; if (claimType == ClaimTypes.Thumbprint) return Thumbprint; #if SUPPORTS_WINDOWSIDENTITY || !disabled if (claimType == ClaimTypes.Upn) return Upn; #endif // SUPPORTS_WINDOWSIDENTITY if (claimType == ClaimTypes.X500DistinguishedName) return X500DistinguishedName; return Default; } public static IEqualityComparer<Claim> Default { get { if (s_defaultComparer == null) { s_defaultComparer = new ClaimComparer(new ObjectComparer()); } return s_defaultComparer; } } public static IEqualityComparer<Claim> Dns { get { if (s_dnsComparer == null) { s_dnsComparer = new ClaimComparer(StringComparer.OrdinalIgnoreCase); } return s_dnsComparer; } } public static IEqualityComparer<Claim> Hash { get { if (s_hashComparer == null) { s_hashComparer = new ClaimComparer(new BinaryObjectComparer()); } return s_hashComparer; } } public static IEqualityComparer<Claim> Rsa { get { if (s_rsaComparer == null) { s_rsaComparer = new ClaimComparer(new RsaObjectComparer()); } return s_rsaComparer; } } public static IEqualityComparer<Claim> Thumbprint { get { if (s_thumbprintComparer == null) { s_thumbprintComparer = new ClaimComparer(new BinaryObjectComparer()); } return s_thumbprintComparer; } } #if SUPPORTS_WINDOWSIDENTITY || !disabled public static IEqualityComparer<Claim> Upn { get { if (s_upnComparer == null) { s_upnComparer = new ClaimComparer(new UpnObjectComparer()); } return s_upnComparer; } } #endif // SUPPORTS_WINDOWSIDENTITY public static IEqualityComparer<Claim> X500DistinguishedName { get { if (s_x500DistinguishedNameComparer == null) { s_x500DistinguishedNameComparer = new ClaimComparer(new X500DistinguishedNameObjectComparer()); } return s_x500DistinguishedNameComparer; } } // we still need to review how the default equals works, this is not how Doug envisioned it. public bool Equals(Claim claim1, Claim claim2) { if (ReferenceEquals(claim1, claim2)) return true; if (claim1 == null || claim2 == null) return false; if (claim1.ClaimType != claim2.ClaimType || claim1.Right != claim2.Right) return false; return _resourceComparer.Equals(claim1.Resource, claim2.Resource); } public int GetHashCode(Claim claim) { if (claim == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claim"); return claim.ClaimType.GetHashCode() ^ claim.Right.GetHashCode() ^ ((claim.Resource == null) ? 0 : _resourceComparer.GetHashCode(claim.Resource)); } private class ObjectComparer : IEqualityComparer { bool IEqualityComparer.Equals(object obj1, object obj2) { if (obj1 == null && obj2 == null) return true; if (obj1 == null || obj2 == null) return false; return obj1.Equals(obj2); } int IEqualityComparer.GetHashCode(object obj) { if (obj == null) return 0; return obj.GetHashCode(); } } private class BinaryObjectComparer : IEqualityComparer { bool IEqualityComparer.Equals(object obj1, object obj2) { if (ReferenceEquals(obj1, obj2)) return true; byte[] bytes1 = obj1 as byte[]; byte[] bytes2 = obj2 as byte[]; if (bytes1 == null || bytes2 == null) return false; if (bytes1.Length != bytes2.Length) return false; for (int i = 0; i < bytes1.Length; ++i) { if (bytes1[i] != bytes2[i]) return false; } return true; } int IEqualityComparer.GetHashCode(object obj) { byte[] bytes = obj as byte[]; if (bytes == null) return 0; int hashCode = 0; for (int i = 0; i < bytes.Length && i < 4; ++i) { hashCode = (hashCode << 8) | bytes[i]; } return hashCode ^ bytes.Length; } } private class RsaObjectComparer : IEqualityComparer { bool IEqualityComparer.Equals(object obj1, object obj2) { if (ReferenceEquals(obj1, obj2)) return true; throw ExceptionHelper.PlatformNotSupported(); } int IEqualityComparer.GetHashCode(object obj) { throw ExceptionHelper.PlatformNotSupported(); } } private class X500DistinguishedNameObjectComparer : IEqualityComparer { private IEqualityComparer _binaryComparer; public X500DistinguishedNameObjectComparer() { _binaryComparer = new BinaryObjectComparer(); } bool IEqualityComparer.Equals(object obj1, object obj2) { if (ReferenceEquals(obj1, obj2)) return true; throw ExceptionHelper.PlatformNotSupported(); } int IEqualityComparer.GetHashCode(object obj) { throw ExceptionHelper.PlatformNotSupported(); } } #if SUPPORTS_WINDOWSIDENTITY || !disabled private class UpnObjectComparer : IEqualityComparer { bool IEqualityComparer.Equals(object obj1, object obj2) { throw ExceptionHelper.PlatformNotSupported(); } int IEqualityComparer.GetHashCode(object obj) { throw new NotImplementedException(); } } #endif // SUPPORTS_WINDOWSIDENTITY } }