Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
    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);
Ejemplo n.º 4
0
        /// <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,
        });
    }