private void StartRefreshTask() { _refreshTask = Task.Run(async() => { while (true) { try { TokenRefreshEntity firstToRefresh = _tokenRefreshEntities.Values .OrderBy(entity => entity.NextRefreshTime).FirstOrDefault(); if (firstToRefresh == null || firstToRefresh.NextRefreshTime > DateTimeOffset.UtcNow) { TimeSpan sleepTime = firstToRefresh == null ? TimeSpan.FromMilliseconds(-1) : (firstToRefresh.NextRefreshTime - DateTimeOffset.UtcNow); await Task.Delay(sleepTime, _cts.Token); } else { await RefreshTokenAsync(firstToRefresh); } } catch (TaskCanceledException) { _cts = new CancellationTokenSource(); } catch (Exception) { } } }); }
public void Register(string subscriptionId, Region tokenIssueRegion = Region.EastAsia) { if (_tokenRefreshEntities.TryGetValue(subscriptionId, out TokenRefreshEntity entity)) { entity.TokenIssueRegion = tokenIssueRegion; } else { entity = new TokenRefreshEntity { SubscriptionId = subscriptionId, TokenIssueRegion = tokenIssueRegion }; _tokenRefreshEntities[subscriptionId] = entity; _firstRunEventSlims[subscriptionId] = new ManualResetEventSlim(false); Task.Run(async() => { await RefreshTokenAsync(entity); _firstRunEventSlims.TryGetValue(subscriptionId, out ManualResetEventSlim eventSlim); eventSlim?.Set(); _cts.Cancel(); }); } }
/// <summary> /// Process token /// </summary> /// <param name="response">Provider token response</param> /// <param name="securityToken">Provider token deta</param> /// <returns></returns> private string ProcessToken(ProviderTokenResponse response, JwtSecurityToken securityToken) { var email = securityToken.Claims.FirstOrDefault(c => c.Type == "email").Value ?? ""; var refreshTokenResponse = this.refreshTokenRespository.GetRefreshTokenByEmailAndProvider(email, securityToken.Issuer); if (string.IsNullOrWhiteSpace(response.RefreshToken)) { return(refreshTokenResponse?.RefreshToken ?? ""); } else { var entity = new TokenRefreshEntity { RefreshToken = response.RefreshToken, Provider = securityToken.Issuer, Email = email, DateUpdated = DateTime.Now }; if (refreshTokenResponse == null) { refreshTokenResponse = this.refreshTokenRespository.InsertRefreshToken(entity); return(entity.RefreshToken); } else { entity.Id = refreshTokenResponse.Id; refreshTokenResponse = this.refreshTokenRespository.UpdateRefreshToken(entity); return(entity.RefreshToken); } } }
/// <summary> /// Insert refresh token /// </summary> /// <param name="refreshToken">Entity</param> /// <returns></returns> public TokenRefreshEntity InsertRefreshToken(TokenRefreshEntity refreshToken) { var parameters = new DynamicParameters(); parameters.Add("@RefreshToken", refreshToken.RefreshToken, DbType.String, ParameterDirection.Input); parameters.Add("@Provider", refreshToken.Provider, DbType.String, ParameterDirection.Input); parameters.Add("@Email", refreshToken.Email, DbType.String, ParameterDirection.Input); var sq = @"INSERT INTO [dbo].[OAuthRefreshTokens] ([Provider] ,[RefreshToken] ,[Email]) VALUES (@Provider, @RefreshToken, @Email)"; return(this.dapperCore.Insert <TokenRefreshEntity>(sq, parameters)); }
/// <summary> /// Insert refresh token /// </summary> /// <param name="refreshToken">Entity</param> /// <returns></returns> public TokenRefreshEntity UpdateRefreshToken(TokenRefreshEntity refreshToken) { var parameters = new DynamicParameters(); parameters.Add("@RefreshToken", refreshToken.RefreshToken, DbType.String, ParameterDirection.Input); parameters.Add("@Provider", refreshToken.Provider, DbType.String, ParameterDirection.Input); parameters.Add("@Email", refreshToken.Email, DbType.String, ParameterDirection.Input); parameters.Add("@Id", refreshToken.Id, DbType.Guid, ParameterDirection.Input); parameters.Add("@DateUpdated", refreshToken.DateUpdated, DbType.DateTime, ParameterDirection.Input); var sq = @"UPDATE [dbo].[OAuthRefreshTokens] SET [Provider] = @Provider ,[RefreshToken] = @RefreshToken ,[Email] = @Email ,[DateUpdated] = @DateUpdated WHERE Id = @Id"; return(this.dapperCore.Update <TokenRefreshEntity>(sq, parameters)); }
private async Task RefreshTokenAsync(TokenRefreshEntity refreshEntity) { _httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", refreshEntity.SubscriptionId); HttpResponseMessage result = await _httpClient.PostAsync(refreshEntity.TokenIssueRegion.GetIssueTokenUri(), null); if (result.IsSuccessStatusCode) { string token = await result.Content.ReadAsStringAsync(); refreshEntity.Token = token; refreshEntity.LastRefreshTime = DateTimeOffset.UtcNow; } else { refreshEntity.LastRefreshTime = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(9 - 0.3); throw new Exception($"Get token fail with status code :[{result.StatusCode}], with message [{result.Content.ReadAsStringAsync()}]"); } }