예제 #1
0
        /// <summary>
        /// Finds a named collection of <see cref="SecurityKey"/>(s) that match the <see cref="SecurityKeyIdentifierClause"/> and returns a <see cref="NamedKeySecurityToken"/> that contains the <see cref="SecurityKey"/>(s).
        /// </summary>
        /// <param name="keyIdentifierClause">The <see cref="SecurityKeyIdentifier"/> to resolve to a <see cref="SecurityToken"/></param>
        /// <param name="token">The resolved <see cref="SecurityToken"/>.</param>
        /// <remarks>If there is no match, then <see cref="IssuerTokenResolver"/> and 'base' are called in order.</remarks>
        /// <returns>true if token was resolved.</returns>
        /// <exception cref="ArgumentNullException">if 'keyIdentifierClause' is null.</exception>
        protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
        {
            if (keyIdentifierClause == null)
            {
                throw new ArgumentNullException("keyIdentifierClause");
            }

            token = null;
            NamedKeySecurityKeyIdentifierClause namedKeyIdentifierClause = keyIdentifierClause as NamedKeySecurityKeyIdentifierClause;

            if (namedKeyIdentifierClause != null)
            {
                IList <SecurityKey> resolvedKeys = null;
                if (this.keys.TryGetValue(namedKeyIdentifierClause.Name, out resolvedKeys))
                {
                    token = new NamedKeySecurityToken(namedKeyIdentifierClause.Name, namedKeyIdentifierClause.Id, resolvedKeys);
                    return(true);
                }
            }

            if (IssuerTokenResolver != null && IssuerTokenResolver.TryResolveToken(keyIdentifierClause, out token))
            {
                return(true);
            }

            return(base.TryResolveTokenCore(keyIdentifierClause, out token));
        }
예제 #2
0
        /// <summary>
        /// Gets the first<see cref="SecurityKey"/> that matches a <see cref="SecurityKeyIdentifierClause"/>
        /// </summary>
        /// <param name="keyIdentifierClause">the <see cref="SecurityKeyIdentifierClause"/> to match.</param>
        /// <returns>The first <see cref="SecurityKey"/> that matches the <see cref="SecurityKeyIdentifierClause"/>.
        /// <para>null if there is no match.</para></returns>
        /// <para>Only <see cref="NamedKeySecurityKeyIdentifierClause"/> are matched.</para>
        /// <exception cref="ArgumentNullException">'keyIdentifierClause' is null.</exception>
        public override SecurityKey ResolveKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause)
        {
            if (keyIdentifierClause == null)
            {
                throw new ArgumentNullException("keyIdentifierClause");
            }

            // if name matches, return first non null
            NamedKeySecurityKeyIdentifierClause namedKeyIdentifierClause = keyIdentifierClause as NamedKeySecurityKeyIdentifierClause;

            if (namedKeyIdentifierClause != null)
            {
                if (string.Equals(namedKeyIdentifierClause.Name, this.name, StringComparison.Ordinal))
                {
                    foreach (SecurityKey securityKey in this.securityKeys)
                    {
                        if (securityKey == null)
                        {
                            continue;
                        }

                        return(securityKey);
                    }
                }
            }

            return(null);
        }
        protected override void ValidateTestCase( string testVariation )
        {
            IdentityConfiguration identityConfig = new IdentityConfiguration( IdentityConfiguration.DefaultServiceName );

            Assert.IsNotNull( identityConfig.IssuerTokenResolver );

            Assert.IsFalse( identityConfig.IssuerTokenResolver.GetType() != typeof( NamedKeyIssuerTokenResolver ) , string.Format( "Expected identityConfiguration.IsuerTokenResolver.GetType() == typeof( NamedKeyIssuerTokenResolver ), was: '{0}'", identityConfig.IssuerTokenResolver.GetType() ) );

            NamedKeyIssuerTokenResolver resolver = identityConfig.IssuerTokenResolver as NamedKeyIssuerTokenResolver;

            Assert.IsTrue( resolver.SecurityKeys.Count == 0 );
            Assert.IsTrue( IssuerTokenResolver.DefaultStoreName == StoreName.TrustedPeople );
            Assert.IsTrue( IssuerTokenResolver.DefaultStoreLocation == StoreLocation.LocalMachine );

            // Should not find key
            SecurityKey key = null;
            NamedKeySecurityKeyIdentifierClause clause = new NamedKeySecurityKeyIdentifierClause( "keyName", "KeyingMaterial.SymmetricKeyBytes_256" );

            Assert.IsFalse( resolver.TryResolveSecurityKey( clause, out key ) );
            Assert.IsNull( key );

            // Should not find token
            SecurityToken token = null;
            Assert.IsFalse( resolver.TryResolveToken( clause, out token ) );
            Assert.IsNull( token );
        }
        public void NamedKeySecurityKeyIdentifierClause_Constructor()
        {
            NamedKeySecurityKeyIdentifierClause namedKeySecurityKeyIdentifierClause;
            ExpectedException expectedException = new ExpectedException(typeExpected: typeof(ArgumentNullException), substringExpected: "name");
            try
            {
                namedKeySecurityKeyIdentifierClause = new NamedKeySecurityKeyIdentifierClause(null, null);
                expectedException.ProcessNoException();
            }
            catch(Exception exception)
            {
                expectedException.ProcessException(exception);
            }

            expectedException = new ExpectedException(typeExpected: typeof(ArgumentNullException), substringExpected: "id");
            try
            {
                namedKeySecurityKeyIdentifierClause = new NamedKeySecurityKeyIdentifierClause("name", null);
                expectedException.ProcessNoException();
            }
            catch (Exception exception)
            {
                expectedException.ProcessException(exception);
            }

            expectedException = ExpectedException.ArgumentNullException(substringExpected: "name");
            try
            {
                namedKeySecurityKeyIdentifierClause = new NamedKeySecurityKeyIdentifierClause(name: "     ", id: "id");
                expectedException.ProcessNoException();
            }
            catch (Exception exception)
            {
                expectedException.ProcessException(exception);
            }

            expectedException = ExpectedException.ArgumentNullException(substringExpected: "id");
            try
            {
                namedKeySecurityKeyIdentifierClause = new NamedKeySecurityKeyIdentifierClause("name", "     ");
                expectedException.ProcessNoException();
            }
            catch (Exception exception)
            {
                expectedException.ProcessException(exception);
            }
        }
예제 #5
0
        /// <summary>
        /// Answers if the <see cref="SecurityKeyIdentifierClause"/> is a match.
        /// </summary>
        /// <param name="keyIdentifierClause">The <see cref="SecurityKeyIdentifierClause"/></param>
        /// <returns>true if matched.</returns>
        /// <remarks><para>A successful match occurs when <see cref="NamedKeySecurityKeyIdentifierClause.Name"/> == <see cref="Id"/>.</para>
        /// <para>Only <see cref="NamedKeySecurityKeyIdentifierClause"/> are matched.</para></remarks>
        /// <exception cref="ArgumentNullException">'keyIdentifierClause' is null.</exception>
        public override bool MatchesKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause)
        {
            if (keyIdentifierClause == null)
            {
                throw new ArgumentNullException("keyIdentifierClause");
            }

            NamedKeySecurityKeyIdentifierClause namedKeyIdentifierClause = keyIdentifierClause as NamedKeySecurityKeyIdentifierClause;

            if (namedKeyIdentifierClause != null)
            {
                if (string.Equals(namedKeyIdentifierClause.Name, this.name, StringComparison.Ordinal))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="JwtHeader"/> class. With the Header Parameters as follows:
        /// <para>{ { typ, JWT }, { alg, Mapped( <see cref="System.IdentityModel.Tokens.SigningCredentials.SignatureAlgorithm"/> } }
        /// See: Algorithm Mapping below.</para>
        /// </summary>
        /// <param name="signingCredentials">The <see cref="SigningCredentials"/> that will be or were used to sign the <see cref="JwtSecurityToken"/>.</param>
        /// <remarks>
        /// <para>For each <see cref="SecurityKeyIdentifierClause"/> in signingCredentials.SigningKeyIdentifier</para>
        /// <para>if the clause  is a <see cref="NamedKeySecurityKeyIdentifierClause"/> Header Parameter { clause.Name, clause.KeyIdentifier } will be added.</para>
        /// <para>For example, if clause.Name == 'kid' and clause.KeyIdentifier == 'SecretKey99'. The JSON object { kid, SecretKey99 } would be added.</para>
        /// <para>In addition, if the <see cref="SigningCredentials"/> is a <see cref="X509SigningCredentials"/> the JSON object { x5t, Base64UrlEncoded( <see cref="X509Certificate.GetCertHashString()"/> } will be added.</para>
        /// <para>This simplifies the common case where a X509Certificate is used.</para>
        /// <para>================= </para>
        /// <para>Algorithm Mapping</para>
        /// <para>================= </para>
        /// <para><see cref="System.IdentityModel.Tokens.SigningCredentials.SignatureAlgorithm"/> describes the algorithm that is discoverable by the CLR runtime.</para>
        /// <para>The  { alg, 'value' } placed in the header reflects the JWT specification.</para>
        /// <see cref="JwtSecurityTokenHandler.OutboundAlgorithmMap"/> contains a signature mapping where the 'value' above will be translated according to this mapping.
        /// <para>Current mapping is:</para>
        /// <para>&#160;&#160;&#160;&#160;'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' => 'RS256'</para>
        /// <para>&#160;&#160;&#160;&#160;'http://www.w3.org/2001/04/xmldsig-more#hmac-sha256' => 'HS256'</para>
        /// </remarks>
        public JwtHeader(SigningCredentials signingCredentials = null)
            : base(StringComparer.Ordinal)
        {
            this.Add(JwtConstants.ReservedHeaderParameters.Type, JwtConstants.HeaderType);

            if (signingCredentials != null)
            {
                this.signingCredentials = signingCredentials;

                string algorithm = signingCredentials.SignatureAlgorithm;
                if (JwtSecurityTokenHandler.OutboundAlgorithmMap.ContainsKey(signingCredentials.SignatureAlgorithm))
                {
                    algorithm = JwtSecurityTokenHandler.OutboundAlgorithmMap[algorithm];
                }

                this.Add(JwtConstants.ReservedHeaderParameters.Algorithm, algorithm);
                if (signingCredentials.SigningKeyIdentifier != null)
                {
                    foreach (SecurityKeyIdentifierClause clause in signingCredentials.SigningKeyIdentifier)
                    {
                        NamedKeySecurityKeyIdentifierClause namedKeyClause = clause as NamedKeySecurityKeyIdentifierClause;
                        if (namedKeyClause != null)
                        {
                            this.Add(namedKeyClause.Name, namedKeyClause.KeyIdentifier);
                        }
                    }
                }

                X509SigningCredentials x509SigningCredentials = signingCredentials as X509SigningCredentials;
                if (x509SigningCredentials != null && x509SigningCredentials.Certificate != null)
                {
                    this.Add(JwtConstants.ReservedHeaderParameters.X509CertificateThumbprint, Base64UrlEncoder.Encode(x509SigningCredentials.Certificate.GetCertHash()));
                }
            }
            else
            {
                this.Add(JwtConstants.ReservedHeaderParameters.Algorithm, JwtConstants.Algorithms.NONE);
            }
        }
        public override ReadOnlyCollection<ClaimsIdentity> ValidateToken(SecurityToken token)
        {
            SimpleWebToken swt = token as SimpleWebToken;
            if (swt == null)
            {
                throw new SecurityTokenValidationException("The received token is of incorrect token type.Expected SimpleWebToken");
            }

            // check issuer name registry for allowed issuers
            string issuerName = swt.Issuer;
            
            // check expiration
            if (DateTime.Compare(swt.ValidTo, DateTime.UtcNow) <= 0)
            {
                throw new SecurityTokenExpiredException("The incoming token has expired. Get a new access token from the Authorization Server.");
            }

            // check audience
            if (base.Configuration.AudienceRestriction.AudienceMode != AudienceUriMode.Never)
            {
                var allowedAudiences = base.Configuration.AudienceRestriction.AllowedAudienceUris;

                if (!allowedAudiences.Any(uri => uri == swt.AudienceUri))
                {
                    throw new AudienceUriValidationFailedException();
                }
            }

            // retrieve signing key
            var clause = new NamedKeySecurityKeyIdentifierClause(swt.Issuer, swt.Issuer);
            var securityKey = Configuration.IssuerTokenResolver.ResolveSecurityKey(clause) as InMemorySymmetricSecurityKey;

            if (securityKey == null)
            {
                throw new SecurityTokenValidationException("No signing key found");
            }

            // check signature
            if (!swt.VerifySignature(securityKey.GetSymmetricKey()))
            {
                throw new SecurityTokenValidationException("Signature verification of the incoming token failed.");
            }

            var id = new ClaimsIdentity("SWT");
            foreach (var claim in swt.Claims)
            {
                var value = claim.Value;
                value.Split(',').ToList().ForEach(v => id.AddClaim(new Claim(claim.Type, HttpUtility.UrlDecode(v), ClaimValueTypes.String, issuerName)));
            }

            return new ReadOnlyCollection<ClaimsIdentity>(new ClaimsIdentity[] { id });
        }
        public void NamedKeySecurityKeyIdentifierClause_Extensibility()
        {
            string clauseName = "kid";
            string keyId = Issuers.GotJwt;

            NamedKeySecurityKeyIdentifierClause clause = new NamedKeySecurityKeyIdentifierClause(clauseName, keyId);
            SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier(clause);
            SigningCredentials signingCredentials = new SigningCredentials(KeyingMaterial.DefaultSymmetricSecurityKey_256, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest, keyIdentifier);
            JwtHeader jwtHeader = new JwtHeader(signingCredentials);
            SecurityKeyIdentifier ski = jwtHeader.SigningKeyIdentifier;
            Assert.AreEqual(ski.Count, 1, "ski.Count != 1 ");

            NamedKeySecurityKeyIdentifierClause clauseOut = ski.Find<NamedKeySecurityKeyIdentifierClause>();
            Assert.IsNotNull(clauseOut, "NamedKeySecurityKeyIdentifierClause not found");
            Assert.AreEqual(clauseOut.Name, clauseName, "clauseOut.Id != clauseId");
            Assert.AreEqual(clauseOut.Id, keyId, "clauseOut.KeyIdentifier != keyId");

            NamedKeySecurityToken NamedKeySecurityToken = new NamedKeySecurityToken(clauseName, keyId, new SecurityKey[] { KeyingMaterial.DefaultSymmetricSecurityKey_256 });
            Assert.IsTrue(NamedKeySecurityToken.MatchesKeyIdentifierClause(clause), "NamedKeySecurityToken.MatchesKeyIdentifierClause( clause ), failed");

            List<SecurityKey> list = new List<SecurityKey>() { KeyingMaterial.DefaultSymmetricSecurityKey_256 };
            Dictionary<string, IList<SecurityKey>> keys = new Dictionary<string, IList<SecurityKey>>() { { "kid", list }, };
            NamedKeyIssuerTokenResolver nkitr = new NamedKeyIssuerTokenResolver(keys: keys);
            SecurityKey sk = nkitr.ResolveSecurityKey(clause);
            Assert.IsNotNull(sk, "NamedKeySecurityToken.MatchesKeyIdentifierClause( clause ), failed");
        }
        public void NamedKeySecurityKeyIdentifierClause_Publics()
        {
            //        new NameKeyParametersVariation
            //{
            //    TestCase = "MatchesName",
            //    TestAction =
            //        () => (new NamedKeySecurityKeyIdentifierClause("bob", null)).Matches(null)
            //},

            NamedKeySecurityKeyIdentifierClause namedKeySecurityKeyIdentifierClause = new NamedKeySecurityKeyIdentifierClause("name", "keyidentifier");
            Assert.IsTrue("name" == namedKeySecurityKeyIdentifierClause.Name);
            Assert.IsTrue("keyidentifier" == namedKeySecurityKeyIdentifierClause.Id);

            // *** Matches (null)
            ExpectedException expectedException = new ExpectedException(typeExpected: typeof(ArgumentNullException), substringExpected: "keyIdentifierClause");
            try
            {
                namedKeySecurityKeyIdentifierClause.Matches(null);
                expectedException.ProcessNoException();
            }
            catch (Exception exception)
            {
                expectedException.ProcessException(exception);
            }

        }
 public void NamedKeySecurityKeyIdentifierClause_Defaults()
 {
     NamedKeySecurityKeyIdentifierClause namedKeySecurityKeyIdentifierClause = new NamedKeySecurityKeyIdentifierClause("name", "keyidentifier");
     Assert.IsTrue("NamedKeySecurityKeyIdentifierClause" == namedKeySecurityKeyIdentifierClause.ClauseType);
 }