< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.IdentityModel.Tokens.AuthorizationPolicy
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Tokens/AuthorizationPolicy.cs
Line coverage
58%
Covered lines: 40
Uncovered lines: 28
Coverable lines: 68
Total lines: 278
Line coverage: 58.8%
Branch coverage
56%
Covered branches: 28
Total branches: 50
Branch coverage: 56%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%1133.33%
.ctor(...)0%220%
.ctor(...)75%4487.5%
Evaluate(...)50%181861.11%
CreateClaimsPrincipalFromIdentities(...)66.66%6675%
CreateFromIdentity(...)50%8855.55%
SelectPrimaryIdentity(...)66.66%121257.14%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Tokens/AuthorizationPolicy.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.ObjectModel;
 7using System.Security.Claims;
 8using System.Security.Principal;
 9using CoreWCF.IdentityModel.Policy;
 10using SysClaimSet = CoreWCF.IdentityModel.Claims.ClaimSet;
 11
 12namespace CoreWCF.IdentityModel.Tokens
 13{
 14    /// <summary>
 15    /// Defines an AuthorizationPolicy that carries the IDFx Claims. When IDFx is enabled
 16    /// a new set of Security Token Authenticators are added to the system. These Authenticators
 17    /// will generate the new Claims defined in System.Security.Claims.
 18    /// </summary>
 19    internal class AuthorizationPolicy : IAuthorizationPolicy
 20    {
 21        public const string ClaimsPrincipalKey = "ClaimsPrincipal"; // This key must be different from "Principal". "Pri
 22        public const string IdentitiesKey = "Identities";
 2823        private readonly List<ClaimsIdentity> _identityCollection = new List<ClaimsIdentity>();
 24
 25        /// <summary>
 26        /// Initializes an instance of <see cref="AuthorizationPolicy"/>
 27        /// </summary>
 028        public AuthorizationPolicy()
 29        {
 030        }
 31
 32        /// <summary>
 33        /// Initializes an instance of <see cref="AuthorizationPolicy"/>
 34        /// </summary>
 35        /// <param name="identity">ClaimsIdentity for the AuthorizationPolicy.</param>
 36        /// <exception cref="ArgumentNullException">One of the input argument is null.</exception>
 037        public AuthorizationPolicy(ClaimsIdentity identity)
 38        {
 039            if (identity == null)
 40            {
 041                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(identity));
 42            }
 43
 044            _identityCollection.Add(identity);
 045        }
 46
 47        /// <summary>
 48        /// Initializes an instance of <see cref="AuthorizationPolicy"/>
 49        /// </summary>
 50        /// <param name="identityCollection">Collection of identities.</param>
 2851        public AuthorizationPolicy(IEnumerable<ClaimsIdentity> identityCollection)
 52        {
 2853            if (identityCollection == null)
 54            {
 055                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(identityCollection));
 56            }
 57
 2858            List<ClaimsIdentity> collection = new List<ClaimsIdentity>();
 11259            foreach (ClaimsIdentity identity in identityCollection)
 60            {
 2861                collection.Add(identity);
 62            }
 63
 2864            _identityCollection = collection;
 2865        }
 66
 67        /// <summary>
 68        /// Gets a ClaimsIdentity collection.
 69        /// </summary>
 70        public ReadOnlyCollection<ClaimsIdentity> IdentityCollection
 71        {
 72            get
 73            {
 074                return _identityCollection.AsReadOnly();
 75            }
 76        }
 77
 78        #region IAuthorizationPolicy Members
 79
 80        /// <summary>
 81        /// Evaluates the current Policy. This is provided for backward compatibility
 82        /// of WCF Claims model. We always return true without affecting the EvaluationContext.
 83        /// </summary>
 84        /// <param name="evaluationContext">The current EvaluationContext.</param>
 85        /// <param name="state">The reference state object.</param>
 86        /// <returns>True if the Policy was successfully applied.</returns>
 87        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
 88        {
 2889            if (null == evaluationContext || null == evaluationContext.Properties)
 90            {
 091                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(evaluationContext));
 92            }
 93
 2894            if (0 == _identityCollection.Count)
 95            {
 96                //
 97                // Nothing to do here.
 98                //
 099                return true;
 100            }
 101
 102            //
 103            // Locate or create the ClaimsPrincipal
 104            //
 28105            if (!evaluationContext.Properties.TryGetValue(ClaimsPrincipalKey, out object principalObj))
 106            {
 28107                ClaimsPrincipal principalToAdd = CreateClaimsPrincipalFromIdentities(_identityCollection);
 108
 28109                evaluationContext.Properties.Add(ClaimsPrincipalKey, principalToAdd);
 110            }
 111            else
 112            {
 0113                if (principalObj is ClaimsPrincipal principal && null != principal.Identities)
 114                {
 0115                    principal.AddIdentities(_identityCollection);
 116                }
 117                else
 118                {
 119                }
 120            }
 121
 122            //
 123            // Locate or create evaluationContext.Properties[ "Identities" ] with identities
 124            //
 28125            if (!evaluationContext.Properties.TryGetValue(IdentitiesKey, out object identitiesObj))
 126            {
 28127                List<ClaimsIdentity> identities = new List<ClaimsIdentity>();
 112128                foreach (ClaimsIdentity ici in _identityCollection)
 129                {
 28130                    identities.Add(ici);
 131                }
 132
 28133                evaluationContext.Properties.Add(IdentitiesKey, identities);
 134            }
 135            else
 136            {
 137                List<ClaimsIdentity> identities;
 0138                identities = identitiesObj as List<ClaimsIdentity>;
 139
 0140                foreach (ClaimsIdentity ici in _identityCollection)
 141                {
 0142                    identities.Add(ici);
 143                }
 144            }
 145
 28146            return true;
 147        }
 148
 149        private static ClaimsPrincipal CreateClaimsPrincipalFromIdentities(IEnumerable<ClaimsIdentity> identities)
 150        {
 28151            ClaimsIdentity selectedClaimsIdentity = SelectPrimaryIdentity(identities);
 152
 28153            if (selectedClaimsIdentity == null)
 154            {
 155                //return an anonymous identity
 0156                return new ClaimsPrincipal(new ClaimsIdentity());
 157            }
 158
 28159            ClaimsPrincipal principal = CreateFromIdentity(selectedClaimsIdentity);
 160
 161            // Add the remaining identities.
 112162            foreach (ClaimsIdentity identity in identities)
 163            {
 28164                if (identity != selectedClaimsIdentity)
 165                {
 0166                    principal.AddIdentity(identity);
 167                }
 168            }
 169
 28170            return principal;
 171        }
 172
 173        /// <summary>
 174        /// Creates the appropriate implementation of an IClaimsPrincipal base on the
 175        /// type of the specified IIdentity (e.g. WindowsClaimsPrincipal for a WindowsIdentity).
 176        /// Note the appropriate IClaimsIdentity is generated based on the specified IIdentity
 177        /// as well.
 178        /// </summary>
 179        /// <param name="identity">An implementation of IIdentity</param>
 180        /// <returns>A claims-based principal.</returns>
 181        private static ClaimsPrincipal CreateFromIdentity(IIdentity identity)
 182        {
 28183            if (null == identity)
 184            {
 0185                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(identity));
 186            }
 187
 28188            if (identity is WindowsIdentity wci)
 189            {
 0190                return new WindowsPrincipal(wci);
 191            }
 192
 28193            if (identity is WindowsIdentity wi)
 194            {
 0195                return new WindowsPrincipal(wi);
 196            }
 197
 28198            if (identity is ClaimsIdentity ici)
 199            {
 28200                return new ClaimsPrincipal(ici);
 201            }
 202
 0203            return new ClaimsPrincipal(new ClaimsIdentity(identity));
 204        }
 205
 206        /// <summary>
 207        /// This method iterates through the collection of ClaimsIdentities
 208        /// and determines which identity must be used as the primary one.
 209        /// </summary>
 210        /// <remarks>
 211        /// If the identities collection contains a WindowsClaimsIdentity, it is the most preferred.
 212        /// If the identities collection contains an RsaClaimsIdentity, it is the least preferred.
 213        /// </remarks>
 214        private static ClaimsIdentity SelectPrimaryIdentity(IEnumerable<ClaimsIdentity> identities)
 215        {
 28216            if (identities == null)
 217            {
 0218                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(identities));
 219            }
 220
 221            //
 222            // Loop through the identities to determine the primary identity.
 223            //
 28224            ClaimsIdentity selectedClaimsIdentity = null;
 225
 112226            foreach (ClaimsIdentity identity in identities)
 227            {
 28228                if (identity is WindowsIdentity)
 229                {
 230                    //
 231                    // If there is a WindowsIdentity, return that.
 232                    //
 0233                    selectedClaimsIdentity = identity;
 0234                    break;
 235                }
 28236                else if (identity.FindFirst(ClaimTypes.Rsa) != null)
 237                {
 238                    //this is a RSA identity
 239                    //it is the least preffered identity
 0240                    if (selectedClaimsIdentity == null)
 241                    {
 0242                        selectedClaimsIdentity = identity;
 243                    }
 244
 0245                    continue;
 246                }
 28247                else if (selectedClaimsIdentity == null)
 248                {
 249                    //
 250                    // If no primary identity has been selected yet, choose the current identity.
 251                    //
 28252                    selectedClaimsIdentity = identity;
 253                }
 254            }
 255
 28256            return selectedClaimsIdentity;
 257        }
 258
 259
 260        /// <summary>
 261        /// Gets the Issuer Claimset. This will return a DefaultClaimSet with just one claim
 262        /// whose ClaimType is http://schemas.microsoft.com/claims/identityclaim.
 263        /// </summary>
 28264        public SysClaimSet Issuer { get; } = SysClaimSet.System;
 265
 266        #endregion
 267
 268        #region IAuthorizationComponent Members
 269
 270        /// <summary>
 271        /// Returns an Id for the ClaimsPrincipal.
 272        /// </summary>
 28273        public string Id { get; } = SecurityUniqueId.Create().Value;
 274
 275        #endregion
 276    }
 277
 278}