< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.IdentityModel.Selectors.SamlSecurityTokenAuthenticator
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Selectors/SamlSecurityTokenAuthenticator.cs
Line coverage
10%
Covered lines: 10
Uncovered lines: 87
Coverable lines: 97
Total lines: 233
Line coverage: 10.3%
Branch coverage
1%
Covered branches: 1
Total branches: 84
Branch coverage: 1.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
.ctor(...)50%22100%
CanValidateTokenCore(...)100%11100%
ValidateTokenCoreAsync()0%36360%
ValidateAudienceRestriction(...)0%12120%
ResolveClaimSetAsyc()0%880%
ResolveClaimSet(...)0%660%
ResolveIdentityAsync()0%14140%
ResolveIdentity(...)0%440%
IsCurrentlyTimeEffective(...)0%220%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Selectors/SamlSecurityTokenAuthenticator.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.Principal;
 8using System.Threading.Tasks;
 9using CoreWCF.IdentityModel.Claims;
 10using CoreWCF.IdentityModel.Policy;
 11using CoreWCF.IdentityModel.Tokens;
 12using CoreWCF.Security;
 13using MSSaml = Microsoft.IdentityModel.Tokens.Saml;
 14
 15namespace CoreWCF.IdentityModel.Selectors
 16{
 17    public class SamlSecurityTokenAuthenticator : SecurityTokenAuthenticator
 18    {
 19        private readonly List<SecurityTokenAuthenticator> _supportingAuthenticators;
 20        private AudienceUriMode _audienceUriMode;
 21        private TimeSpan _maxClockSkew;
 22
 23        public SamlSecurityTokenAuthenticator(IList<SecurityTokenAuthenticator> supportingAuthenticators)
 224            : this(supportingAuthenticators, TimeSpan.Zero)
 225        { }
 26
 227        public SamlSecurityTokenAuthenticator(IList<SecurityTokenAuthenticator> supportingAuthenticators, TimeSpan maxCl
 28        {
 229            _supportingAuthenticators = new List<SecurityTokenAuthenticator>(supportingAuthenticators ??
 230                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(supportingAuthenticators)));
 231            _maxClockSkew = maxClockSkew;
 232            _audienceUriMode = AudienceUriMode.Always;
 233        }
 34
 35        public AudienceUriMode AudienceUriMode
 36        {
 037            get { return _audienceUriMode; }
 38            set
 39            {
 040                AudienceUriModeValidationHelper.Validate(_audienceUriMode);
 041                _audienceUriMode = value;
 042            }
 43        }
 44
 245        public IList<string> AllowedAudienceUris { get; } = new Collection<string>();
 46
 47        protected override bool CanValidateTokenCore(SecurityToken token)
 48        {
 18849            return token is SamlSecurityToken;
 50        }
 51
 52        protected override async ValueTask<ReadOnlyCollection<IAuthorizationPolicy>> ValidateTokenCoreAsync(SecurityToke
 53        {
 054            if (token == null)
 055                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(token));
 56
 57
 058            if (!(token is SamlSecurityToken samlToken))
 059                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.SamlTo
 60
 061            if (samlToken.Assertion.Signature == null)
 062                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.SamlTo
 63
 064            if (!IsCurrentlyTimeEffective(samlToken))
 065                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.SAMLTo
 66
 067            if (samlToken.SigningToken == null)
 068                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.SamlSi
 69
 70            // Build the Issuer ClaimSet for this Saml token.
 071            ClaimSet issuer = null;
 072            bool canBeValidated = false;
 073            for (int i = 0; i < _supportingAuthenticators.Count; ++i)
 74            {
 075                canBeValidated = _supportingAuthenticators[i].CanValidateToken(samlToken.SigningToken);
 076                if (canBeValidated)
 77                    break;
 78            }
 079            if (!canBeValidated)
 080                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.SamlIn
 81
 082            issuer = (await ResolveClaimSetAsyc(samlToken.SigningToken)) ?? ClaimSet.Anonymous;
 83
 084            List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>();
 085            foreach (InternalSamlSubjectStatement subject in samlToken.SamlStatements)
 86            {
 087                policies.Add(await subject.CreatePolicyAsync(issuer, this));
 88            }
 89
 090            if ((_audienceUriMode == AudienceUriMode.Always)
 091             || (_audienceUriMode == AudienceUriMode.BearerKeyOnly) && (samlToken.SecurityKeys.Count < 1))
 92            {
 93                // throws if not found.
 094                bool foundAudienceCondition = false;
 095                if (AllowedAudienceUris == null)
 96                {
 097                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.SA
 98                }
 99
 0100                foreach (MSSaml.SamlCondition samlCondition in samlToken.Assertion.Conditions.Conditions)
 101                {
 0102                    if (samlCondition is MSSaml.SamlAudienceRestrictionCondition condition)
 103                    {
 0104                        foundAudienceCondition = true;
 0105                        if (!ValidateAudienceRestriction(condition))
 106                        {
 0107                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Form
 108                        }
 109                    }
 110                }
 111
 0112                if (!foundAudienceCondition)
 0113                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.SA
 114            }
 115
 0116            return policies.AsReadOnly();
 0117        }
 118
 119        protected virtual bool ValidateAudienceRestriction(MSSaml.SamlAudienceRestrictionCondition audienceRestrictionCo
 120        {
 0121            foreach (Uri audienceUri in audienceRestrictionCondition.Audiences)
 122            {
 0123                if (audienceUri == null)
 124                    continue;
 125
 0126                for (int j = 0; j < AllowedAudienceUris.Count; j++)
 127                {
 0128                    if (StringComparer.Ordinal.Compare(audienceUri.AbsoluteUri, AllowedAudienceUris[j]) == 0)
 0129                        return true;
 0130                    else if (Uri.IsWellFormedUriString(AllowedAudienceUris[j], UriKind.Absolute))
 131                    {
 0132                        Uri uri = new Uri(AllowedAudienceUris[j]);
 0133                        if (audienceUri.Equals(uri))
 0134                            return true;
 135                    }
 136                }
 137            }
 138
 0139            return false;
 0140        }
 141
 142        public virtual async ValueTask<ClaimSet> ResolveClaimSetAsyc(SecurityToken token)
 143        {
 0144            if (token == null)
 0145                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(token));
 146
 0147            foreach (var authenticator in _supportingAuthenticators)
 148            {
 0149                if (authenticator.CanValidateToken(token))
 150                {
 0151                    var authorizationPolicies = await authenticator.ValidateTokenAsync(token); ;
 0152                    AuthorizationContext authContext = AuthorizationContext.CreateDefaultAuthorizationContext(authorizat
 0153                    if (authContext.ClaimSets.Count > 0)
 154                    {
 0155                        return authContext.ClaimSets[0];
 156                    }
 157                }
 158            }
 159
 0160            return null;
 0161        }
 162
 163        public virtual ClaimSet ResolveClaimSet(SecurityKeyIdentifier keyIdentifier)
 164        {
 0165            if (keyIdentifier == null)
 0166                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(keyIdentifier));
 167
 0168            if (keyIdentifier.TryFind(out RsaKeyIdentifierClause rsaKeyIdentifierClause))
 169            {
 0170                return new DefaultClaimSet(new Claim(ClaimTypes.Rsa, rsaKeyIdentifierClause.Rsa, Rights.PossessProperty)
 171            }
 0172            else if (keyIdentifier.TryFind(out EncryptedKeyIdentifierClause encryptedKeyIdentifierClause))
 173            {
 0174                return new DefaultClaimSet(Claim.CreateHashClaim(encryptedKeyIdentifierClause.GetBuffer()));
 175            }
 176
 0177            return null;
 178        }
 179
 180        public virtual async ValueTask<IIdentity> ResolveIdentityAsync(SecurityToken token)
 181        {
 0182            if (token == null)
 0183                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(token));
 184
 0185            for (int i = 0; i < _supportingAuthenticators.Count; ++i)
 186            {
 0187                if (_supportingAuthenticators[i].CanValidateToken(token))
 188                {
 0189                    ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = await _supportingAuthenticators[i].
 0190                    if (authorizationPolicies != null && authorizationPolicies.Count != 0)
 191                    {
 0192                        for (int j = 0; j < authorizationPolicies.Count; ++j)
 193                        {
 0194                            IAuthorizationPolicy policy = authorizationPolicies[j];
 0195                            if (policy is UnconditionalPolicy policy1)
 196                            {
 0197                                return policy1.PrimaryIdentity;
 198                            }
 199                        }
 200                    }
 201                }
 202            }
 203
 0204            return null;
 0205        }
 206
 207        public virtual IIdentity ResolveIdentity(SecurityKeyIdentifier keyIdentifier)
 208        {
 0209            if (keyIdentifier == null)
 0210                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(keyIdentifier));
 211
 0212            if (keyIdentifier.TryFind(out RsaKeyIdentifierClause rsaKeyIdentifierClause))
 213            {
 0214                return SecurityUtils.CreateIdentity(rsaKeyIdentifierClause.Rsa.ToXmlString(false), GetType().Name);
 215            }
 216
 0217            return null;
 218        }
 219
 220        private bool IsCurrentlyTimeEffective(SamlSecurityToken token)
 221        {
 0222            if (token.Assertion.Conditions != null)
 223            {
 0224                return SecurityUtils.IsCurrentlyTimeEffective(token.Assertion.Conditions.NotBefore, token.Assertion.Cond
 225            }
 226
 227            // If SAML Condition is not present then the assertion is valid at any given time.
 0228            return true;
 229        }
 230
 231    }
 232
 233}