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); }
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"); } }
void IInMemoryPublicKeyCache.Set(string srcNamespace, D2LSecurityToken key) { m_cache.Set( key: BuildCacheKey(srcNamespace, key.KeyId), value: key, new MemoryCacheEntryOptions { AbsoluteExpiration = key.ValidTo } ); }
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)); }
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); }