< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.Tokens.SecurityContextCookieSerializer
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/Tokens/SecurityContextCookieSerializer.cs
Line coverage
2%
Covered lines: 3
Uncovered lines: 137
Coverable lines: 140
Total lines: 309
Line coverage: 2.1%
Branch coverage
2%
Covered branches: 2
Total branches: 76
Branch coverage: 2.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)50%44100%
DeserializeContext(...)0%42420%
CreateCookieFromSecurityContext(...)0%16160%
CreateSecurityContextFromCookie(...)0%660%
OnInvalidCookieFailure(...)100%110%
OnInvalidCookieFailure(...)100%110%
.ctor(...)100%110%
Evaluate(...)0%880%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/Tokens/SecurityContextCookieSerializer.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.IO;
 8using System.Runtime.Serialization;
 9using System.Security.Principal;
 10using System.Xml;
 11using CoreWCF.Dispatcher;
 12using CoreWCF.IdentityModel;
 13using CoreWCF.IdentityModel.Claims;
 14using CoreWCF.IdentityModel.Policy;
 15using CoreWCF.Runtime;
 16
 17namespace CoreWCF.Security.Tokens
 18{
 19    internal struct SecurityContextCookieSerializer
 20    {
 21        private const int SupportedPersistanceVersion = 1;
 22        private readonly SecurityStateEncoder _securityStateEncoder;
 23        private readonly IList<Type> _knownTypes;
 24
 25        public SecurityContextCookieSerializer(SecurityStateEncoder securityStateEncoder, IList<Type> knownTypes)
 26        {
 13327            _securityStateEncoder = securityStateEncoder ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument
 13328            _knownTypes = knownTypes ?? new List<Type>();
 13329        }
 30
 31        private SecurityContextSecurityToken DeserializeContext(byte[] serializedContext, byte[] cookieBlob, string id, 
 32        {
 033            SctClaimDictionary dictionary = SctClaimDictionary.Instance;
 034            XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(serializedContext, 0, serializedContext.
 035            int cookieVersion = -1;
 036            UniqueId cookieContextId = null;
 037            DateTime effectiveTime = SecurityUtils.MinUtcDateTime;
 038            DateTime expiryTime = SecurityUtils.MaxUtcDateTime;
 039            byte[] key = null;
 040            string localId = null;
 041            UniqueId keyGeneration = null;
 042            DateTime keyEffectiveTime = SecurityUtils.MinUtcDateTime;
 043            DateTime keyExpirationTime = SecurityUtils.MaxUtcDateTime;
 044            List<ClaimSet> claimSets = null;
 045            IList<IIdentity> identities = null;
 046            bool isCookie = true;
 47
 048            reader.ReadFullStartElement(dictionary.SecurityContextSecurityToken, dictionary.EmptyString);
 49
 050            while (reader.IsStartElement())
 51            {
 052                if (reader.IsStartElement(dictionary.Version, dictionary.EmptyString))
 53                {
 054                    cookieVersion = reader.ReadElementContentAsInt();
 55                }
 056                else if (reader.IsStartElement(dictionary.ContextId, dictionary.EmptyString))
 57                {
 058                    cookieContextId = reader.ReadElementContentAsUniqueId();
 59                }
 060                else if (reader.IsStartElement(dictionary.Id, dictionary.EmptyString))
 61                {
 062                    localId = reader.ReadElementContentAsString();
 63                }
 064                else if (reader.IsStartElement(dictionary.EffectiveTime, dictionary.EmptyString))
 65                {
 066                    effectiveTime = new DateTime(XmlHelper.ReadElementContentAsInt64(reader), DateTimeKind.Utc);
 67                }
 068                else if (reader.IsStartElement(dictionary.ExpiryTime, dictionary.EmptyString))
 69                {
 070                    expiryTime = new DateTime(XmlHelper.ReadElementContentAsInt64(reader), DateTimeKind.Utc);
 71                }
 072                else if (reader.IsStartElement(dictionary.Key, dictionary.EmptyString))
 73                {
 074                    key = reader.ReadElementContentAsBase64();
 75                }
 076                else if (reader.IsStartElement(dictionary.KeyGeneration, dictionary.EmptyString))
 77                {
 078                    keyGeneration = reader.ReadElementContentAsUniqueId();
 79                }
 080                else if (reader.IsStartElement(dictionary.KeyEffectiveTime, dictionary.EmptyString))
 81                {
 082                    keyEffectiveTime = new DateTime(XmlHelper.ReadElementContentAsInt64(reader), DateTimeKind.Utc);
 83                }
 084                else if (reader.IsStartElement(dictionary.KeyExpiryTime, dictionary.EmptyString))
 85                {
 086                    keyExpirationTime = new DateTime(XmlHelper.ReadElementContentAsInt64(reader), DateTimeKind.Utc);
 87                }
 088                else if (reader.IsStartElement(dictionary.Identities, dictionary.EmptyString))
 89                {
 090                    identities = SctClaimSerializer.DeserializeIdentities(reader, dictionary, DataContractSerializerDefa
 91                }
 092                else if (reader.IsStartElement(dictionary.ClaimSets, dictionary.EmptyString))
 93                {
 094                    reader.ReadStartElement();
 95
 096                    DataContractSerializer claimSetSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(C
 097                    DataContractSerializer claimSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(Clai
 098                    claimSets = new List<ClaimSet>(1);
 099                    while (reader.IsStartElement())
 100                    {
 0101                        claimSets.Add(SctClaimSerializer.DeserializeClaimSet(reader, dictionary, claimSetSerializer, cla
 102                    }
 103
 0104                    reader.ReadEndElement();
 105                }
 0106                else if (reader.IsStartElement(dictionary.IsCookieMode, dictionary.EmptyString))
 107                {
 0108                    isCookie = reader.ReadElementString() == "1" ? true : false;
 109                }
 110                else
 111                {
 0112                    OnInvalidCookieFailure(SR.Format(SR.SctCookieXmlParseError));
 113                }
 114            }
 0115            reader.ReadEndElement();
 0116            if (cookieVersion != SupportedPersistanceVersion)
 117            {
 0118                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.Seriali
 119            }
 0120            if (cookieContextId == null)
 121            {
 0122                OnInvalidCookieFailure(SR.Format(SR.SctCookieValueMissingOrIncorrect, nameof(cookieContextId)));
 123            }
 0124            if (key == null || key.Length == 0)
 125            {
 0126                OnInvalidCookieFailure(SR.Format(SR.SctCookieValueMissingOrIncorrect, nameof(key)));
 127            }
 0128            if (localId != id)
 129            {
 0130                OnInvalidCookieFailure(SR.Format(SR.SctCookieValueMissingOrIncorrect, nameof(id)));
 131            }
 132            List<IAuthorizationPolicy> authorizationPolicies;
 0133            if (claimSets != null)
 134            {
 0135                authorizationPolicies = new List<IAuthorizationPolicy>(1)
 0136                {
 0137                    new SctUnconditionalPolicy(identities, claimSets, expiryTime)
 0138                };
 139            }
 140            else
 141            {
 0142                authorizationPolicies = null;
 143            }
 0144            return new SecurityContextSecurityToken(cookieContextId, localId, key, effectiveTime, expiryTime,
 0145                authorizationPolicies?.AsReadOnly(), isCookie, cookieBlob, keyGeneration, keyEffectiveTime, keyExpiratio
 146        }
 147
 148        public byte[] CreateCookieFromSecurityContext(UniqueId contextId, string id, byte[] key, DateTime tokenEffective
 149            DateTime tokenExpirationTime, UniqueId keyGeneration, DateTime keyEffectiveTime, DateTime keyExpirationTime,
 150            ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies)
 151        {
 0152            if (contextId == null)
 153            {
 0154                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(contextId));
 155            }
 156
 0157            if (key == null)
 158            {
 0159                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(key));
 160            }
 161
 0162            MemoryStream stream = new MemoryStream();
 0163            XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream, SctClaimDictionary.Instance, nul
 164
 0165            SctClaimDictionary dictionary = SctClaimDictionary.Instance;
 0166            writer.WriteStartElement(dictionary.SecurityContextSecurityToken, dictionary.EmptyString);
 0167            writer.WriteStartElement(dictionary.Version, dictionary.EmptyString);
 0168            writer.WriteValue(SupportedPersistanceVersion);
 0169            writer.WriteEndElement();
 0170            if (id != null)
 171            {
 0172                writer.WriteElementString(dictionary.Id, dictionary.EmptyString, id);
 173            }
 174
 0175            XmlHelper.WriteElementStringAsUniqueId(writer, dictionary.ContextId, dictionary.EmptyString, contextId);
 176
 0177            writer.WriteStartElement(dictionary.Key, dictionary.EmptyString);
 0178            writer.WriteBase64(key, 0, key.Length);
 0179            writer.WriteEndElement();
 180
 0181            if (keyGeneration != null)
 182            {
 0183                XmlHelper.WriteElementStringAsUniqueId(writer, dictionary.KeyGeneration, dictionary.EmptyString, keyGene
 184            }
 185
 0186            XmlHelper.WriteElementContentAsInt64(writer, dictionary.EffectiveTime, dictionary.EmptyString, tokenEffectiv
 0187            XmlHelper.WriteElementContentAsInt64(writer, dictionary.ExpiryTime, dictionary.EmptyString, tokenExpirationT
 0188            XmlHelper.WriteElementContentAsInt64(writer, dictionary.KeyEffectiveTime, dictionary.EmptyString, keyEffecti
 0189            XmlHelper.WriteElementContentAsInt64(writer, dictionary.KeyExpiryTime, dictionary.EmptyString, keyExpiration
 190
 0191            AuthorizationContext authContext = null;
 0192            if (authorizationPolicies != null)
 193            {
 0194                authContext = AuthorizationContext.CreateDefaultAuthorizationContext(authorizationPolicies);
 195            }
 196
 0197            if (authContext != null && authContext.ClaimSets.Count != 0)
 198            {
 0199                DataContractSerializer identitySerializer = DataContractSerializerDefaults.CreateSerializer(typeof(IIden
 0200                DataContractSerializer claimSetSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(Claim
 0201                DataContractSerializer claimSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(Claim), 
 0202                SctClaimSerializer.SerializeIdentities(authContext, dictionary, writer, identitySerializer);
 203
 0204                writer.WriteStartElement(dictionary.ClaimSets, dictionary.EmptyString);
 0205                for (int i = 0; i < authContext.ClaimSets.Count; i++)
 206                {
 0207                    SctClaimSerializer.SerializeClaimSet(authContext.ClaimSets[i], dictionary, writer, claimSetSerialize
 208                }
 0209                writer.WriteEndElement();
 210            }
 211
 0212            writer.WriteEndElement();
 0213            writer.Flush();
 214
 0215            byte[] serializedContext = stream.ToArray();
 0216            return _securityStateEncoder.EncodeSecurityState(serializedContext);
 217        }
 218
 219        public SecurityContextSecurityToken CreateSecurityContextFromCookie(byte[] encodedCookie, UniqueId contextId, Un
 220        {
 0221            byte[] cookie = null;
 222
 223            try
 224            {
 0225                cookie = _securityStateEncoder.DecodeSecurityState(encodedCookie);
 0226            }
 0227            catch (Exception e)
 228            {
 0229                if (Fx.IsFatal(e))
 230                {
 0231                    throw;
 232                }
 0233                OnInvalidCookieFailure(SR.Format(SR.SctCookieBlobDecodeFailure), e);
 0234            }
 0235            SecurityContextSecurityToken sct = DeserializeContext(cookie, encodedCookie, id, quotas);
 0236            if (sct.ContextId != contextId)
 237            {
 0238                OnInvalidCookieFailure(SR.Format(SR.SctCookieValueMissingOrIncorrect, nameof(contextId)));
 239            }
 0240            if (sct.KeyGeneration != generation)
 241            {
 0242                OnInvalidCookieFailure(SR.Format(SR.SctCookieValueMissingOrIncorrect, nameof(sct.KeyGeneration)));
 243            }
 244
 0245            return sct;
 246        }
 247
 248        internal static void OnInvalidCookieFailure(string reason)
 249        {
 0250            OnInvalidCookieFailure(reason, null);
 0251        }
 252
 253        internal static void OnInvalidCookieFailure(string reason, Exception e)
 254        {
 0255            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.InvalidS
 256        }
 257
 258        internal class SctUnconditionalPolicy : IAuthorizationPolicy
 259        {
 0260            private readonly SecurityUniqueId _id = SecurityUniqueId.Create();
 261            private readonly IList<IIdentity> _identities;
 262            private readonly IList<ClaimSet> _claimSets;
 263            private readonly DateTime _expirationTime;
 264
 0265            public SctUnconditionalPolicy(IList<IIdentity> identities, IList<ClaimSet> claimSets, DateTime expirationTim
 266            {
 0267                _identities = identities;
 0268                _claimSets = claimSets;
 0269                _expirationTime = expirationTime;
 0270            }
 271
 272            public string Id
 273            {
 0274                get { return _id.Value; }
 275            }
 276
 277            public ClaimSet Issuer
 278            {
 0279                get { return ClaimSet.System; }
 280            }
 281
 282            public bool Evaluate(EvaluationContext evaluationContext, ref object state)
 283            {
 0284                for (int i = 0; i < _claimSets.Count; ++i)
 285                {
 0286                    evaluationContext.AddClaimSet(this, _claimSets[i]);
 287                }
 288
 0289                if (_identities != null)
 290                {
 0291                    if (!evaluationContext.Properties.TryGetValue(SecurityUtils.Identities, out object obj))
 292                    {
 0293                        evaluationContext.Properties.Add(SecurityUtils.Identities, _identities);
 294                    }
 295                    else
 296                    {
 297                        // null if other overrides the property with something else
 0298                        if (obj is List<IIdentity> dstIdentities)
 299                        {
 0300                            dstIdentities.AddRange(_identities);
 301                        }
 302                    }
 303                }
 0304                evaluationContext.RecordExpirationTime(_expirationTime);
 0305                return true;
 306            }
 307        }
 308    }
 309}