async public void ItShouldRetrieveJwksAndCacheKeysWhenKeyIsNotInCache() { var seq = new MockSequence(); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, KEY_ID)) .Returns <D2LSecurityToken>(null); var otherKeyId = Guid.NewGuid(); var jwks = new JsonWebKeySet( new JavaScriptSerializer().Serialize( new { keys = new object[] { D2LSecurityTokenUtility .CreateActiveToken(KEY_ID) .ToJsonWebKey() .ToJwkDto(), D2LSecurityTokenUtility .CreateActiveToken(otherKeyId) .ToJsonWebKey() .ToJwkDto() } } ), new Uri("http://localhost/dummy") ); m_jwksProvider .InSequence(seq) .Setup(x => x.RequestJwksAsync()) .ReturnsAsync(jwks); m_keyCache .Setup(x => x.Set(SRC_NAMESPACE, It.Is <D2LSecurityToken>(k => k.KeyId == KEY_ID))); m_keyCache .Setup(x => x.Set(SRC_NAMESPACE, It.Is <D2LSecurityToken>(k => k.KeyId == otherKeyId))); var cachedKey = new D2LSecurityToken( KEY_ID, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(1), () => null as Tuple <AsymmetricSecurityKey, IDisposable> ); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, KEY_ID)) .Returns(cachedKey); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync(KEY_ID) .SafeAsync(); m_keyCache.VerifyAll(); Assert.AreEqual(cachedKey, result); }
public async Task ItShouldRetrieveJwksAndIgnoreInvalidKeysWithoutErroring(string keyId) { var seq = new MockSequence(); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, keyId)) .Returns <D2LSecurityToken>(null); var otherKeyId = Guid.NewGuid().ToString(); var jwks = new JsonWebKeySet( JsonSerializer.Serialize( new { keys = new[] { D2LSecurityTokenUtility .CreateActiveToken(keyId) .ToJsonWebKey() .ToJwkDto(), D2LSecurityTokenUtility .CreateTokenWithTimeRemaining(TimeSpan.FromSeconds(-1), otherKeyId) .ToJsonWebKey() .ToJwkDto() } } ), new Uri("http://localhost/dummy") ); m_jwksProvider .InSequence(seq) .Setup(x => x.RequestJwkAsync(keyId)) .ReturnsAsync(jwks); m_keyCache .Setup(x => x.Set(SRC_NAMESPACE, It.Is <D2LSecurityToken>(k => k.KeyId == keyId))); var cachedKey = new D2LSecurityToken( keyId, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(1), () => null as Tuple <AsymmetricSecurityKey, IDisposable> ); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, keyId)) .Returns(cachedKey); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync(keyId) .ConfigureAwait(false); m_keyCache.VerifyAll(); m_keyCache.Verify(x => x.Set(SRC_NAMESPACE, It.IsAny <D2LSecurityToken>()), Times.Once); Assert.AreEqual(cachedKey, result); }
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"); } }