/// <summary> /// Creates and returns a permission that is the intersection of the current permission and the specified permission. /// </summary> /// <returns> /// A new permission that represents the intersection of the current permission and the specified permission. This new permission is null if the intersection is empty. /// </returns> /// <param name="target">A permission to intersect with the current permission. It must be of the same type as the current permission. </param><exception cref="T:System.ArgumentException">The <paramref name="target"/> parameter is not null and is not an instance of the same class as the current permission. </exception> public IPermission Intersect(IPermission target) { //returns a new permission object that represents the intersection of two permissions. //In the ClaimsPrincipalPermission, this is implemented in the following manner: // - If the permission to intersect with is null, null is returned. // - If the permission to intersect with is not a ClaimsPrincipalPermission type, null is returned. // - If either the permission to intersect or this permission is unrestricted, return a copy of the //opposite permission. // - If IsAuthenticated does not match for both permissions, null is returned. // - If ALL of the Issuer claims are not matched, null is returned. The assumption here is that a //developer is providing another permission to intersect with, and they should thus describe the //Issuer with the same set of claims. This simplifies how developers can use these permissions, by //reducing the complexity that would follow if you attempted to intersect the ClaimSet of an Issuer, //and the Issuer’s Issuer, and that Issuer’s Issuer, and so on. In other words, the nature of the //ClaimSet and the nested Issuer claim sets demands simplicity here. //Once the Issuer ClaimSet is verified as a perfect match between permissions, the actual claim sets //can be intersected. So long as they are issued by the same Issuer, the list of required claim sets //in both permissions can be intersected to produce a new ClaimSet by the same Issuer. if (target == null) return null; ClaimsPrincipalPermission perm = target as ClaimsPrincipalPermission; if (perm == null) return null; if (this.IsUnrestricted()) return target.Copy(); if (perm.IsUnrestricted()) return this.Copy(); if (this.isAuthenticated != perm.IsAuthenticated) return null; if (!IsExactIssuerMatch(perm.Issuer)) return null; List<Claim> claims = this.requiredClaims.Where(c => perm.RequiredClaims.ContainsClaim(c)).ToList(); // it is assumed that the issuers are identical from the call // to IsExactIssuerMatch() above ClaimsPrincipalPermission newPerm = new ClaimsPrincipalPermission(this.isAuthenticated, new DefaultClaimSet(this.requiredClaims.Issuer, claims)); return newPerm; }
/// <summary> /// Creates a permission that is the union of the current permission and the specified permission. /// </summary> /// <returns> /// A new permission that represents the union of the current permission and the specified permission. /// </returns> /// <param name="target">A permission to combine with the current permission. It must be of the same type as the current permission. </param><exception cref="T:System.ArgumentException">The <paramref name="target"/> parameter is not null and is not of the same type as the current permission. </exception> public IPermission Union(IPermission target) { //returns a new permission type that includes all of the required claims of two permissions, assuming //that they both share the same setting for IsAuthenticated and Issuer values. Similar validation on //the permission passed to the method, the IsAuthenticated property and the Issuer value are executed //before creating a new permission type with the entire set of claims (without duplicates). if (target == null) return null; ClaimsPrincipalPermission perm = target as ClaimsPrincipalPermission; if (perm == null) return null; if (perm.IsUnrestricted() || this.IsUnrestricted()) return new ClaimsPrincipalPermission(PermissionState.Unrestricted); if (this.isAuthenticated != perm.IsAuthenticated) return null; if (!IsExactIssuerMatch(perm.Issuer)) return null; List<Claim> claims = this.requiredClaims.ToList(); claims.AddRange(perm.RequiredClaims.Where(c => !this.requiredClaims.ContainsClaim(c))); // it is assumed that the issuers are identical from the call // to IsExactIssuerMatch() above ClaimsPrincipalPermission newPerm = new ClaimsPrincipalPermission(this.isAuthenticated, new DefaultClaimSet(this.requiredClaims.Issuer, claims)); return newPerm; }