/// <inheritdoc/> public async Task <string> GetUserAccessTokenAsync(bool forceRenewal = false) { var user = _httpContextAccessor.HttpContext.User; var userName = user.FindFirst(JwtClaimTypes.Name)?.Value ?? user.FindFirst(JwtClaimTypes.Subject)?.Value ?? "unknown"; var userToken = await _userTokenStore.GetTokenAsync(_httpContextAccessor.HttpContext.User); var dtRefresh = userToken.Expiration.Subtract(_options.User.RefreshBeforeExpiration); if ((dtRefresh < _clock.UtcNow) || forceRenewal == true) { _logger.LogDebug("Token for user {user} needs refreshing.", userName); try { return(await _userRefreshDictionary.GetOrAdd(userToken.RefreshToken, (string refreshToken) => { return new Lazy <Task <string> >(async() => { var refreshed = await RefreshUserAccessTokenAsync(); return refreshed.AccessToken; }); }).Value); } finally { _userRefreshDictionary.TryRemove(userToken.RefreshToken, out _); } } return(userToken.AccessToken); }
/// <inheritdoc/> public async Task <string> GetUserAccessTokenAsync(ClaimsPrincipal user, bool forceRenewal = false) { if (user == null || !user.Identity.IsAuthenticated) { return(null); } var userName = user.FindFirst(JwtClaimTypes.Name)?.Value ?? user.FindFirst(JwtClaimTypes.Subject)?.Value ?? "unknown"; var userToken = await _userTokenStore.GetTokenAsync(user); if (userToken == null) { _logger.LogDebug("No token data found in user token store."); return(null); } if (string.IsNullOrWhiteSpace(userToken.RefreshToken)) { _logger.LogDebug("No refresh token found in user token store for user {user}. Returning current access token.", userName); return(userToken.AccessToken); } var dtRefresh = userToken.Expiration.Subtract(_options.User.RefreshBeforeExpiration); if (dtRefresh < _clock.UtcNow || forceRenewal == true) { _logger.LogDebug("Token for user {user} needs refreshing.", userName); try { return(await UserRefreshDictionary.GetOrAdd(userToken.RefreshToken, _ => { return new Lazy <Task <string> >(async() => { var refreshed = await RefreshUserAccessTokenAsync(user); return refreshed.AccessToken; }); }).Value); } finally { UserRefreshDictionary.TryRemove(userToken.RefreshToken, out _); } } return(userToken.AccessToken); }
public async Task <string?> GetTokenAsync(string tenantId, string userId) { var protectionProvider = GetProtectionProvider(tenantId: tenantId, userId: userId); var protectedTokenString = await _decorated.GetTokenAsync(tenantId : tenantId, userId : userId); if (protectedTokenString == default) { _logger.LogInformation("Decorated store did not have token, returning null"); return(default);
/// <inheritdoc/> public async Task <string> GetUserAccessTokenAsync( ClaimsPrincipal user, UserAccessTokenParameters parameters = null, CancellationToken cancellationToken = default) { parameters ??= new UserAccessTokenParameters(); if (user == null || !user.Identity.IsAuthenticated) { return(null); } var userName = user.FindFirst(JwtClaimTypes.Name)?.Value ?? user.FindFirst(JwtClaimTypes.Subject)?.Value ?? "unknown"; var userToken = await _userTokenStore.GetTokenAsync(user, parameters); if (userToken == null) { _logger.LogDebug("No token data found in user token store."); return(null); } if (userToken.AccessToken.IsPresent() && userToken.RefreshToken.IsMissing()) { _logger.LogDebug("No refresh token found in user token store for user {user} / resource {resource}. Returning current access token.", userName, parameters.Resource ?? "default"); return(userToken.AccessToken); } if (userToken.AccessToken.IsMissing() && userToken.RefreshToken.IsPresent()) { _logger.LogDebug( "No access token found in user token store for user {user} / resource {resource}. Trying to refresh.", userName, parameters.Resource ?? "default"); } var dtRefresh = DateTimeOffset.MinValue; if (userToken.Expiration.HasValue) { dtRefresh = userToken.Expiration.Value.Subtract(_options.User.RefreshBeforeExpiration); } if (dtRefresh < _clock.UtcNow || parameters.ForceRenewal) { _logger.LogDebug("Token for user {user} needs refreshing.", userName); try { return(await UserRefreshDictionary.GetOrAdd(userToken.RefreshToken, _ => { return new Lazy <Task <string> >(async() => { var refreshed = await RefreshUserAccessTokenAsync(user, parameters, cancellationToken); return refreshed.AccessToken; }); }).Value); } finally { UserRefreshDictionary.TryRemove(userToken.RefreshToken, out _); } } return(userToken.AccessToken); }
public async Task <AccessTokenResultBase> GetAccessTokenAsync(string tenantId, string userId) { var tokenDtoString = await _userTokenStore.GetTokenAsync(tenantId, userId); if (tokenDtoString == default) { _logger.LogInformation("Underlying store contained no token, returning null"); return(GetNeedsConsentResult()); } var tokenDto = JsonSerializer.Deserialize <OAuthUserTokenDto>(tokenDtoString); if (tokenDto == default) { _logger.LogWarning("Token stored was valid json, but not valid DTO! Did the schema change?"); return(GetNeedsConsentResult()); } _logger.LogInformation( "Token expired? [{isExpired}]: [{timeDelta}]", DateTime.Now >= tokenDto.AccessTokenExpiration, DateTime.Now - tokenDto.AccessTokenExpiration); // If the 'cached' token is still valid don't do the refresh. if (tokenDto.AccessTokenExpiration >= DateTime.Now) { return(new AccessTokenResult { AccessToken = tokenDto.AccessToken, }); } _logger.LogInformation("Performing oAuth refresh flow"); var jsonBody = await _oAuthServiceClient.RefreshAccessTokenAsync(tokenDto.RefreshToken); if (jsonBody == default) { return(GetNeedsConsentResult()); } string accessToken = jsonBody.AccessToken != "" ? jsonBody.AccessToken : tokenDto.AccessToken; long expirationSeconds = jsonBody.ExpiresInSeconds; // If we get a refresh token in the response, we need to replace the refresh token. Otherwise re-use the current refresh token. string nextRefreshToken = jsonBody.RefreshToken ?? tokenDto.RefreshToken; var dto = new OAuthUserTokenDto { AccessToken = accessToken, AccessTokenExpiration = DateTimeOffset.Now + TimeSpan.FromSeconds(expirationSeconds), RefreshToken = nextRefreshToken }; var serializedDto = JsonSerializer.Serialize(dto); await _userTokenStore.SetTokenAsync( tenantId : tenantId, userId : userId, token : serializedDto); return(new AccessTokenResult { AccessToken = accessToken, }); }