< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.WrappedTokenCache
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/WrappedTokenCache.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 61
Coverable lines: 61
Total lines: 193
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 26
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)0%440%
AddContext(...)100%110%
ClearContexts()100%110%
GetAllContexts(...)0%880%
GetContext(...)0%440%
RemoveAllContexts(...)100%110%
RemoveContext(...)100%110%
TryAddContext(...)100%110%
UpdateContextCachingTime(...)0%440%
TryResolveSecurityKeyCore(...)0%220%
TryResolveTokenCore(...)0%220%
TryResolveTokenCore(...)0%220%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/WrappedTokenCache.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 CoreWCF.IdentityModel;
 8using CoreWCF.IdentityModel.Selectors;
 9using CoreWCF.IdentityModel.Tokens;
 10using CoreWCF.Security.Tokens;
 11
 12namespace CoreWCF.Security
 13{
 14    /// <summary>
 15    /// The purpose of this class is to provide an ISecurityContextSecurityTokenCache contract over a SecurityTokenCache
 16    /// This allows for a consistent interface for the SecurityContextSecurityTokenHandler and a SessionSecurityTokenHan
 17    /// The SecurityTokenCache can be passed to the SecurityContextSecurityTokenHandler and wrapped to expose an ISecuri
 18    /// that can be set to the be the token cache for WCF context tokens
 19    /// </summary>
 20    internal class WrappedTokenCache : SecurityTokenResolver, ISecurityContextSecurityTokenCache
 21    {
 22        private readonly SessionSecurityTokenCache _tokenCache;
 23        private readonly SctClaimsHandler _claimsHandler;
 24
 025        public WrappedTokenCache(SessionSecurityTokenCache tokenCache, SctClaimsHandler sctClaimsHandler)
 26        {
 027            _tokenCache = tokenCache ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tokenCac
 028            _claimsHandler = sctClaimsHandler ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof
 029        }
 30
 31        #region ISecurityContextSecurityTokenCache Members
 32
 33        public void AddContext(SecurityContextSecurityToken token)
 34        {
 35            //
 36            // WCF will cache the token first before calling the WrappedSessionSecurityTokenHandler.OnTokenIssued.
 37            // We need to map the claims here so we will be caching the correct token with Geneva Claims substitued
 38            // in place of the WCF claims.
 39            //
 040            _claimsHandler.SetPrincipalBootstrapTokensAndBindIdfxAuthPolicy(token);
 41
 042            SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, token.Context
 043            SessionSecurityToken sessionToken = SecurityContextSecurityTokenHelper.ConvertSctToSessionToken(token, Secur
 044            DateTime expiryTime = DateTimeUtil.Add(sessionToken.ValidTo, _claimsHandler.SecurityTokenHandlerCollection.C
 045            _tokenCache.AddOrUpdate(key, sessionToken, expiryTime);
 046        }
 47
 48        public void ClearContexts()
 49        {
 050            _tokenCache.RemoveAll(_claimsHandler.EndpointId);
 051        }
 52
 53        /// <summary>
 54        /// Called to retrieve all tokens that match a particular contextId. WCF will call this
 55        /// </summary>
 56        /// <param name="contextId"></param>
 57        /// <returns></returns>
 58        public Collection<SecurityContextSecurityToken> GetAllContexts(System.Xml.UniqueId contextId)
 59        {
 060            Collection<SecurityContextSecurityToken> tokens = new Collection<SecurityContextSecurityToken>();
 61
 062            IEnumerable<SessionSecurityToken> cachedTokens = _tokenCache.GetAll(_claimsHandler.EndpointId, contextId);
 063            if (cachedTokens != null)
 64            {
 065                foreach (SessionSecurityToken sessionSct in cachedTokens)
 66                {
 067                    if (sessionSct != null && sessionSct.IsSecurityContextSecurityTokenWrapper)
 68                    {
 069                        SecurityContextSecurityToken sctToken = SecurityContextSecurityTokenHelper.ConvertSessionTokenTo
 070                        tokens.Add(sctToken);
 71                    }
 72                }
 73            }
 74
 075            return tokens;
 76        }
 77
 78        public SecurityContextSecurityToken GetContext(System.Xml.UniqueId contextId, System.Xml.UniqueId generation)
 79        {
 080            SessionSecurityToken token = null;
 081            SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, contextId, ge
 082            token = _tokenCache.Get(key);
 83
 084            SecurityContextSecurityToken sctToken = null;
 85
 086            if (token != null && token.IsSecurityContextSecurityTokenWrapper)
 87            {
 088                sctToken = SecurityContextSecurityTokenHelper.ConvertSessionTokenToSecurityContextSecurityToken(token);
 89            }
 90
 091            return sctToken;
 92        }
 93
 94        /// <summary>
 95        /// Removes all the tokens that match the contextId.
 96        /// </summary>
 97        /// <param name="contextId">The context id.</param>
 98        /// <remarks>
 99        /// When WCF renews a token, its context id is the same as the issuedToken. The only
 100        /// difference is in the generationId. When WCF closes the session channel, all the tokens that
 101        /// were issued need to be removed that match the contextId.
 102        /// </remarks>
 103        public void RemoveAllContexts(System.Xml.UniqueId contextId)
 104        {
 0105            _tokenCache.RemoveAll(_claimsHandler.EndpointId, contextId);
 0106        }
 107
 108        public void RemoveContext(System.Xml.UniqueId contextId, System.Xml.UniqueId generation)
 109        {
 0110            SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, contextId, ge
 0111            _tokenCache.Remove(key);
 0112        }
 113
 114        public bool TryAddContext(SecurityContextSecurityToken token)
 115        {
 116            //
 117            // WCF will cache the token first before calling the WrappedSessionSecurityTokenHandler.OnTokenIssued.
 118            // We need to map the claims here so we will be caching the correct token with Geneva Claims substitued
 119            // in place of the WCF claims.
 120            //
 0121            _claimsHandler.SetPrincipalBootstrapTokensAndBindIdfxAuthPolicy(token);
 122
 0123            SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, token.Context
 0124            SessionSecurityToken sessionToken = SecurityContextSecurityTokenHelper.ConvertSctToSessionToken(token, Secur
 0125            DateTime expiryTime = DateTimeUtil.Add(token.ValidTo, _claimsHandler.SecurityTokenHandlerCollection.Configur
 0126            _tokenCache.AddOrUpdate(key, sessionToken, expiryTime);
 0127            return true;
 128        }
 129
 130        public void UpdateContextCachingTime(SecurityContextSecurityToken token, DateTime expirationTime)
 131        {
 0132            if (token.ValidTo <= expirationTime.ToUniversalTime())
 133            {
 0134                return;
 135            }
 136
 0137            SessionSecurityTokenCacheKey key = new SessionSecurityTokenCacheKey(_claimsHandler.EndpointId, token.Context
 0138            SessionSecurityToken sessionToken = SecurityContextSecurityTokenHelper.ConvertSctToSessionToken(token, Secur
 0139            DateTime expiryTime = DateTimeUtil.Add(sessionToken.ValidTo, _claimsHandler.SecurityTokenHandlerCollection.C
 0140            if (_tokenCache.Get(key) == null)
 141            {
 0142                throw DiagnosticUtility.ExceptionUtility.ThrowHelperInvalidOperation(SR.Format(SR.ID4285, sessionToken.C
 143            }
 0144            _tokenCache.AddOrUpdate(key, sessionToken, expiryTime);
 0145        }
 146
 147        #endregion
 148
 149        // these are not needed as this will never be used as an SecurityTokenResolver.
 150        protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityK
 151        {
 152            SecurityToken sct;
 0153            if (TryResolveTokenCore(keyIdentifierClause, out sct))
 154            {
 0155                key = ((SecurityContextSecurityToken)sct).SecurityKeys[0];
 0156                return true;
 157            }
 158            else
 159            {
 0160                key = null;
 0161                return false;
 162            }
 163        }
 164
 165        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken t
 166        {
 0167            SecurityContextKeyIdentifierClause sctSkiClause = keyIdentifierClause as SecurityContextKeyIdentifierClause;
 0168            if (sctSkiClause != null)
 169            {
 0170                token = GetContext(sctSkiClause.ContextId, sctSkiClause.Generation) as SecurityToken;
 171            }
 172            else
 173            {
 0174                token = null;
 175            }
 0176            return (token != null);
 177        }
 178
 179        protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)
 180        {
 181            SecurityContextKeyIdentifierClause sctSkiClause;
 0182            if (keyIdentifier.TryFind<SecurityContextKeyIdentifierClause>(out sctSkiClause))
 183            {
 0184                return TryResolveTokenCore(sctSkiClause, out token);
 185            }
 186            else
 187            {
 0188                token = null;
 0189                return false;
 190            }
 191        }
 192    }
 193}