Beispiel #1
0
        public async Task FromJson_GeneratedECKeyRoundTrips()
        {
            IPrivateKeyProvider privateKeyProvider = new EcDsaPrivateKeyProvider(
                new D2LSecurityTokenFactory(
                    DateTimeProvider.Instance,
                    TimeSpan.FromHours(1)
                    ),
                ECCurve.NamedCurves.nistP256
                );

            JsonWebKey expectedKey;

            using (D2LSecurityToken token = await privateKeyProvider.GetSigningCredentialsAsync().ConfigureAwait(false)) {
                expectedKey = token.ToJsonWebKey();
            }

            string expectedJson = JsonConvert.SerializeObject(expectedKey.ToJwkDto());

            JsonWebKey actualKey  = JsonWebKey.FromJson(expectedJson);
            string     actualJson = JsonConvert.SerializeObject(actualKey.ToJwkDto());

            Assert.AreEqual(expectedKey.Id, actualKey.Id);
            Assert.AreEqual(expectedKey.ExpiresAt.Value.ToUnixTimeSeconds(), actualKey.ExpiresAt.Value.ToUnixTimeSeconds());
            Assert.AreEqual(expectedJson, actualJson);
        }
        public async Task FromJson_GeneratedECKeyRoundTrips()
        {
            IPrivateKeyProvider privateKeyProvider = new EcDsaPrivateKeyProvider(
                new D2LSecurityTokenFactory(
                    DateTimeProvider.Instance,
                    TimeSpan.FromHours(1)
                    ),
                CngAlgorithm.ECDsaP256
                );

            JsonWebKey expectedKey;

            using (D2LSecurityToken token = await privateKeyProvider.GetSigningCredentialsAsync().SafeAsync()) {
                expectedKey = token.ToJsonWebKey();
            }

            string expectedJson = JsonConvert.SerializeObject(expectedKey.ToJwkDto());

            JsonWebKey actualKey  = JsonWebKey.FromJson(expectedJson);
            string     actualJson = JsonConvert.SerializeObject(actualKey.ToJwkDto());

            Assert.AreEqual(expectedKey.Id, actualKey.Id);
            Assert.AreEqual(( long )expectedKey.ExpiresAt.Value.TimeSinceUnixEpoch().TotalSeconds, ( long )actualKey.ExpiresAt.Value.TimeSinceUnixEpoch().TotalSeconds);
            Assert.AreEqual(expectedJson, actualJson);
        }
Beispiel #3
0
        private async Task RunTest(
            bool signJwt,
            DateTime jwtExpiry,
            Type expectedExceptionType = null
            )
        {
            string             keyId              = Guid.NewGuid().ToString();
            D2LSecurityToken   signingToken       = D2LSecurityTokenUtility.CreateActiveToken(id: keyId);
            SigningCredentials signingCredentials = null;

            if (signJwt)
            {
                signingCredentials = signingToken.GetSigningCredentials();
            }

            var jwtToken = new JwtSecurityToken(
                issuer: "someissuer",
                signingCredentials: signingCredentials,
                expires: jwtExpiry
                );

            var    tokenHandler  = new JwtSecurityTokenHandler();
            string serializedJwt = tokenHandler.WriteToken(jwtToken);

            IPublicKeyProvider publicKeyProvider = PublicKeyProviderMock.Create(
                m_jwksEndpoint,
                keyId,
                signingToken
                ).Object;

            IAccessTokenValidator tokenValidator = new AccessTokenValidator(
                publicKeyProvider
                );

            IAccessToken accessToken = null;
            Exception    exception   = null;

            try {
                accessToken = await tokenValidator.ValidateAsync(
                    accessToken : serializedJwt
                    ).ConfigureAwait(false);
            } catch (Exception e) {
                exception = e;
            }

            if (expectedExceptionType != null)
            {
                Assert.IsNull(accessToken, "Unexpected access token returned from validation");
                Assert.IsNotNull(exception, "Expected an exception but got null");
                Assert.AreEqual(expectedExceptionType, exception.GetType(), "Wrong exception type");
            }
            else
            {
                Assert.IsNotNull(accessToken, "Expected an access token but got none");
            }
        }
Beispiel #4
0
 void IInMemoryPublicKeyCache.Set(string srcNamespace, D2LSecurityToken key)
 {
     m_cache.Set(
         key: BuildCacheKey(srcNamespace, key.KeyId),
         value: key,
         new MemoryCacheEntryOptions {
         AbsoluteExpiration = key.ValidTo
     }
         );
 }
Beispiel #5
0
 void IInMemoryPublicKeyCache.Set(string srcNamespace, D2LSecurityToken key)
 {
     m_cache.Set(
         BuildCacheKey(srcNamespace, key.KeyId),
         key,
         new CacheItemPolicy()
     {
         AbsoluteExpiration = key.ValidTo
     }
         );
 }
        internal static Mock <IPublicKeyProvider> Create(
            Uri jwksEndpoint,
            Guid keyId,
            D2LSecurityToken token
            )
        {
            var mock = new Mock <IPublicKeyProvider>();

            mock.Setup(p => p.GetByIdAsync(
                           keyId
                           )).Returns(Task.FromResult(token));

            return(mock);
        }
        public Task <D2LSecurityToken> GetSigningCredentialsAsync()
        {
            var creds = new D2LSecurityToken(
                id: m_keyId,
                validFrom: DateTime.UtcNow - TimeSpan.FromDays(1),
                validTo: DateTime.UtcNow + TimeSpan.FromDays(365),
                keyFactory: () => {
                var csp = new RSACryptoServiceProvider()
                {
                    PersistKeyInCsp = false
                };
                csp.ImportParameters(m_rsaParameters);
                var key = new RsaSecurityKey(csp);
                return(new Tuple <AsymmetricSecurityKey, IDisposable>(key, csp));
            })
                        .Ref();

            return(Task.FromResult(creds));
        }
Beispiel #8
0
        async Task <IAccessToken> IAccessTokenValidator.ValidateAsync(
            string token
            )
        {
            var tokenHandler = m_tokenHandler.Value;

            if (!tokenHandler.CanReadToken(token))
            {
                throw new ValidationException("Couldn't parse token");
            }

            var unvalidatedToken = (JwtSecurityToken)tokenHandler.ReadToken(
                token
                );

            if (!ALLOWED_SIGNATURE_ALGORITHMS.Contains(unvalidatedToken.SignatureAlgorithm))
            {
                string message = string.Format(
                    "Signature algorithm '{0}' is not supported.  Permitted algorithms are '{1}'",
                    unvalidatedToken.SignatureAlgorithm,
                    string.Join(",", ALLOWED_SIGNATURE_ALGORITHMS)
                    );
                throw new InvalidTokenException(message);
            }

            if (!unvalidatedToken.Header.ContainsKey("kid"))
            {
                throw new InvalidTokenException("KeyId not found in token");
            }

            string keyId = unvalidatedToken.Header["kid"].ToString();
            Guid   id;

            if (!Guid.TryParse(keyId, out id))
            {
                throw new InvalidTokenException(string.Format("Non-guid kid claim: {0}", keyId));
            }

            D2LSecurityToken signingToken = await m_publicKeyProvider
                                            .GetByIdAsync(id)
                                            .SafeAsync();

            var validationParameters = new TokenValidationParameters()
            {
                ValidateAudience    = false,
                ValidateIssuer      = false,
                RequireSignedTokens = true,
                IssuerSigningToken  = signingToken
            };

            IAccessToken accessToken;

            try {
                SecurityToken securityToken;
                tokenHandler.ValidateToken(
                    token,
                    validationParameters,
                    out securityToken
                    );
                accessToken = new AccessToken(( JwtSecurityToken )securityToken);
            } catch (SecurityTokenExpiredException e) {
                throw new ExpiredTokenException(e);
            } catch (Exception e) {
                throw new ValidationException("Unknown validation exception", e);
            }

            return(accessToken);
        }
        async Task <IAccessToken> IAccessTokenValidator.ValidateAsync(
            string token
            )
        {
            var tokenHandler = m_tokenHandler.Value;

            if (!tokenHandler.CanReadToken(token))
            {
                throw new ValidationException("Couldn't parse token");
            }

            var unvalidatedToken = ( JwtSecurityToken )tokenHandler.ReadToken(
                token
                );

            if (!ALLOWED_SIGNATURE_ALGORITHMS.Contains(unvalidatedToken.SignatureAlgorithm))
            {
                string message = string.Format(
                    "Signature algorithm '{0}' is not supported.  Permitted algorithms are '{1}'",
                    unvalidatedToken.SignatureAlgorithm,
                    string.Join(",", ALLOWED_SIGNATURE_ALGORITHMS)
                    );
                throw new InvalidTokenException(message);
            }

            if (!unvalidatedToken.Header.ContainsKey("kid"))
            {
                throw new InvalidTokenException("KeyId not found in token");
            }

            string keyId = unvalidatedToken.Header["kid"].ToString();

            D2LSecurityToken signingKey = await m_publicKeyProvider
                                          .GetByIdAsync(keyId)
                                          .ConfigureAwait(false);

            var validationParameters = new TokenValidationParameters()
            {
                ValidateAudience      = false,
                ValidateIssuer        = false,
                RequireSignedTokens   = true,
                IssuerSigningKey      = signingKey,
                CryptoProviderFactory = new D2LCryptoProviderFactory()
            };

            IAccessToken accessToken;

            try {
                tokenHandler.ValidateToken(
                    token,
                    validationParameters,
                    out SecurityToken securityToken
                    );
                accessToken = new AccessToken(( JwtSecurityToken )securityToken);
            } catch (SecurityTokenExpiredException e) {
                throw new ExpiredTokenException(e);
            } catch (SecurityTokenNotYetValidException e) {
                throw new ValidationException("Token is from the future (nbf)", e);
            } catch (Exception e) {
                throw new ValidationException("Unknown validation exception", e);
            }

            return(accessToken);
        }