public async Task Invoke(HttpContext context) { if (!_hasProvider) { await _next(context); return; } try { TokenInfo tokenInfo; if (context.Request.Headers.ContainsKey("Authorization")) { if (context.Request.Headers.TryGetValue("Authorization", out var authzValue) && authzValue.Any(value => value.Contains("Basic"))) { // Add Telemetry. using (var activity = _activitySource?.StartActivity("BasicAuthentication", ActivityKind.Producer)) { var cacheKey = BuildKey(authzValue); tokenInfo = _tokenCache?.Get <TokenInfo>(cacheKey); if (null == tokenInfo || tokenInfo.ExpiresOnUtc < DateTime.UtcNow.AddMinutes(1)) { var credential = GetCredential(authzValue); if (null != credential && credential.CredentialsEntered) { // Get an Access Token. tokenInfo = await _provider.GetTokenAsync(_option.Settings, credential); _tokenCache?.Put(cacheKey, tokenInfo); } } if (null != tokenInfo) { // Replace the Basic Authorization by the access token in the header. var authorization = new AuthenticationHeaderValue("Bearer", tokenInfo.AccessToken).ToString(); context.Request.Headers.Remove("Authorization"); context.Request.Headers.Add("Authorization", authorization); } } } } } catch (Exception ex) { _logger.Technical().Exception(ex).Log(); } await _next(context); }
private void AfterAccessNotification(TokenCacheNotificationArgs args) { if (HasStateChanged) { Logger.Technical().From <Cache>().System($"Adding token information to the cache for the identifier: {_identifier}.").Log(); TokenCache.Put(_identifier, SerializeAdalV3()); Logger.Technical().From <Cache>().System($"Added token information to the cache for the identifier: {_identifier}.").Log(); HasStateChanged = false; } }
public async Task <TokenInfo> GetTokenAsync(IKeyValueSettings settings, CredentialsResult credential) { var messages = GetContext(settings, out string clientId, out string authority, out string authenticationType, out string serviceApplicationId); if (String.IsNullOrWhiteSpace(credential.Upn)) { messages.Add(new Message(ServiceModel.MessageCategory.Technical, ServiceModel.MessageType.Warning, "No Username is provided.")); } if (String.IsNullOrWhiteSpace(credential.Password)) { messages.Add(new Message(ServiceModel.MessageCategory.Technical, ServiceModel.MessageType.Warning, "No password is provided.")); } messages.LogAndThrowIfNecessary(this); messages.Clear(); if (null != TokenCache) { // Get a HashCode from the password so a second call with the same upn but with a wrong password will not be impersonated due to // the lack of password check. var cacheKey = BuildKey(credential, authority, serviceApplicationId); Logger.Technical().From <CredentialTokenCacheTokenProvider>().System($"Check if the cache contains a token for {cacheKey}.").Log(); var tokenInfo = TokenCache.Get <TokenInfo>(cacheKey); var hasChanged = false; if (null != tokenInfo) { Logger.Technical().From <CredentialTokenCacheTokenProvider>().System($"Token loaded from the cache for {cacheKey}.").Log(); if (tokenInfo.ExpiresOnUtc < DateTime.UtcNow.AddMinutes(1)) { Logger.Technical().From <CredentialTokenCacheTokenProvider>().System($"Token is expired for {cacheKey}.").Log(); // We need to refresh the token. tokenInfo = await CreateBasicTokenInfoAsync(settings, credential); hasChanged = true; } } else { Logger.Technical().From <CredentialTokenCacheTokenProvider>().System($"Contact the STS to create an access token for {cacheKey}.").Log(); tokenInfo = await CreateBasicTokenInfoAsync(settings, credential); hasChanged = true; } if (hasChanged) { try { Logger.Technical().From <CredentialTokenCacheTokenProvider>().System($"Save the token in the cache for {cacheKey}, will expire at {tokenInfo.ExpiresOnUtc} Utc.").Log(); TokenCache.Put(cacheKey, tokenInfo); } catch (Exception ex) { Logger.Technical().From <CredentialTokenCacheTokenProvider>().Exception(ex).Log(); } } return(tokenInfo); } // no cache, do a direct call on every calls. Logger.Technical().From <CredentialTokenCacheTokenProvider>().System($"No cache is defined. STS is called for every call.").Log(); return(await CreateBasicTokenInfoAsync(settings, credential)); }