using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using Kreta.Framework.Security; namespace Kreta.Web.Security { public static class ClaimsPrincipalExtensions { /// /// Checks whether a given claim exists /// /// The principal. /// The search predicate. /// true/false public static bool ClaimExists(this ClaimsPrincipal principal, Predicate predicate) { foreach (var identity in principal.Identities) { if (identity.ClaimExists(predicate)) { return true; } } return false; } /// /// Checks whether a given claim exists /// /// The principal. /// Type of the claim. /// true/false public static bool ClaimExists(this ClaimsPrincipal principal, string claimType) { return principal.ClaimExists(c => c.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase)); } /// /// Checks whether a given claim exists. /// /// The principal. /// Type of the claim. /// The value. /// true/false public static bool ClaimExists(this ClaimsPrincipal principal, string claimType, string[] value) { var result = false; foreach (var item in value) { if (principal.ClaimExists(c => c.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && c.Value.Equals(item, StringComparison.OrdinalIgnoreCase))) { result = true; break; } } return result; } /// /// Checks whether a given claim exists. /// /// The principal. /// Type of the claim. /// The value. /// The issuer. /// true/false public static bool ClaimExists(this ClaimsPrincipal principal, string claimType, string[] value, string issuer) { var result = false; foreach (var item in value) { if (principal.ClaimExists(c => c.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && c.Value.Equals(item, StringComparison.OrdinalIgnoreCase) && c.Issuer.Equals(issuer, StringComparison.OrdinalIgnoreCase))) { result = true; break; } } return result; } /// /// Demands a specific claim. /// /// The principal. /// The search predicate. public static void DemandClaim(this ClaimsPrincipal principal, Predicate predicate) { foreach (Claim claim in principal.FindClaims(predicate)) { return; } throw new SecurityException(); } /// /// Demands a specific claim. /// /// The principal. /// Type of the claim. public static void DemandClaim(this ClaimsPrincipal principal, string claimType) { try { principal.DemandClaim(claim => claim.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase)); } catch (SecurityException) { throw new SecurityException(); } } /// /// Demands a specific claim. /// /// The principal. /// Type of the claim. /// The value. public static void DemandClaim(this ClaimsPrincipal principal, string claimType, string value) { try { principal.DemandClaim(claim => claim.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && claim.Value.Equals(value, StringComparison.OrdinalIgnoreCase)); } catch (SecurityException) { throw new SecurityException(); } } /// /// Demands a specific claim. /// /// The principal. /// Type of the claim. /// The value. /// The issuer. public static void DemandClaim(this ClaimsPrincipal principal, string claimType, string value, string issuer) { try { principal.DemandClaim(claim => claim.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && claim.Value.Equals(value, StringComparison.OrdinalIgnoreCase) && claim.Issuer.Equals(issuer, StringComparison.OrdinalIgnoreCase)); } catch (SecurityException) { throw new SecurityException(); } } /// /// Denies a specific claim. /// /// The principal. /// The search predicate. public static void DenyClaim(this ClaimsPrincipal principal, Predicate predicate) { foreach (Claim claim in principal.FindClaims(predicate)) { throw new SecurityException(); } } /// /// Denies a specific claim. /// /// The principal. /// Type of the claim. public static void DenyClaim(this ClaimsPrincipal principal, string claimType) { try { principal.DenyClaim(claim => claim.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase)); } catch (SecurityException) { throw new SecurityException(); } } /// /// Denies a specific claim. /// /// The principal. /// Type of the claim. /// The value. public static void DenyClaim(this ClaimsPrincipal principal, string claimType, string value) { try { principal.DenyClaim(claim => claim.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && claim.Value.Equals(value, StringComparison.OrdinalIgnoreCase)); } catch (SecurityException) { throw new SecurityException(); } } /// /// Denies a specific claim. /// /// The principal. /// Type of the claim. /// The value. /// The issuer. public static void DenyClaim(this ClaimsPrincipal principal, string claimType, string value, string issuer) { try { principal.DenyClaim(claim => claim.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && claim.Value.Equals(value, StringComparison.OrdinalIgnoreCase) && claim.Issuer.Equals(issuer, StringComparison.OrdinalIgnoreCase)); } catch (SecurityException) { throw new SecurityException(); } } /// /// Finds all instances of the specified claim. /// /// The principal. /// A search predicate. /// A list of claims that match the search criteria. public static IEnumerable FindClaims(this ClaimsPrincipal principal, Predicate predicate) { foreach (ClaimsIdentity identity in principal.Identities) { foreach (Claim claim in identity.FindClaims(predicate)) { yield return claim; } } } /// /// Finds all instances of the specified claim. /// /// The principal. /// Type of the claim. /// A list of claims that match the search criteria. public static IEnumerable FindClaims(this ClaimsPrincipal principal, string claimType) { return principal.FindClaims(c => c.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase)); } /// /// Finds all instances of the specified claim. /// /// The principal. /// Type of the claim. /// The issuer. /// A list of claims that match the search criteria. public static IEnumerable FindClaims(this ClaimsPrincipal principal, string claimType, string issuer) { return principal.FindClaims(c => c.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && c.Issuer.Equals(issuer, StringComparison.OrdinalIgnoreCase)); } /// /// Finds all instances of the specified claim. /// /// The principal. /// Type of the claim. /// The issuer. /// The value. /// A list of claims that match the search criteria. public static IEnumerable FindClaims(this ClaimsPrincipal principal, string claimType, string issuer, string value) { return principal.FindClaims(c => c.Type.Equals(claimType, StringComparison.OrdinalIgnoreCase) && c.Value.Equals(value, StringComparison.OrdinalIgnoreCase) && c.Issuer.Equals(issuer, StringComparison.OrdinalIgnoreCase)); } /// /// Finds all instances of the specified claim. /// /// The principal. /// The claim. /// A list of claims that match the search criteria. public static IEnumerable FindClaims(this ClaimsPrincipal principal, Claim claim) { return principal.FindClaims(c => c.Type.Equals(claim.Type, StringComparison.OrdinalIgnoreCase) && c.Value.Equals(claim.Value, StringComparison.OrdinalIgnoreCase) && c.Issuer.Equals(claim.Issuer, StringComparison.OrdinalIgnoreCase)); } /// /// Retrieves the value of a claim. /// /// The principal. /// Type of the claim. /// The value public static string GetClaimValue(this ClaimsPrincipal principal, string claimType) { string value = null; foreach (var identity in principal.Identities) { if (identity.TryGetClaimValue(claimType, out value)) { return value; } } throw new ClaimNotFoundException(claimType); } /// /// Retrieves the value of a claim. /// /// The principal. /// Type of the claim. /// The issuer. /// The value public static string GetClaimValue(this ClaimsPrincipal principal, string claimType, string issuer) { string value = null; foreach (var identity in principal.Identities) { if (identity.TryGetClaimValue(claimType, issuer, out value)) { return value; } } throw new ClaimNotFoundException(claimType); } /// /// Tries to retrieve the value of a claim. /// /// The principal. /// Type of the claim. /// The claim value. /// The value public static bool TryGetClaimValue(this ClaimsPrincipal principal, string claimType, out string claimValue) { claimValue = null; Claim claim = principal.FindClaims(claimType).FirstOrDefault(); if (claim != null) { claimValue = claim.Value; return true; } return false; } /// /// Tries to retrieve the value of a claim. /// /// The principal. /// Type of the claim. /// The issuer. /// The claim value. /// The value public static bool TryGetClaimValue(this ClaimsPrincipal principal, string claimType, string issuer, out string claimValue) { claimValue = null; Claim claim = principal.FindClaims(claimType, issuer).FirstOrDefault(); if (claim != null) { claimValue = claim.Value; return true; } return false; } /// /// Retrieves the first identity of an ClaimsPrincipal. /// /// The principal. /// The first IClaimsIdentity public static ClaimsIdentity First(this ClaimsPrincipal principal) { return principal.Identities.ElementAt(0); } } }