Exemplo n.º 1
0
        public async Task <string> GetAccessToken(ClaimsPrincipal user, CancellationToken cancellationToken = default(CancellationToken))
        {
            var tokens = await GetOidcTokens(user, cancellationToken);

            if (tokens == null)
            {
                _log.LogWarning($"Failed to get OIDC auth tokens for: {user.Identity.Name}, returning null access token");
                return(null);
            }

            var accessToken  = tokens["access_token"];
            var refreshToken = tokens["refresh_token"];
            var exp          = tokens["expires_at"];

            if (string.IsNullOrEmpty(exp) || string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(refreshToken))
            {
                _log.LogWarning($"Cache was not null but still failed to get OIDC auth tokens for: {user.Identity.Name}, returning null access token");
                return(null);
            }

            var dtExpires = DateTimeOffset.Parse(exp, CultureInfo.InvariantCulture);
            var dtRefresh = dtExpires.Subtract(_tokenOptions.RefreshBeforeExpiration);

            if (dtRefresh < _clock.UtcNow)
            {
                var shouldRefresh = _pendingRefreshTokenRequests.TryAdd(refreshToken, true);
                if (shouldRefresh)
                {
                    try
                    {
                        var response = await _oidcTokenEndpointService.RefreshTokenAsync(refreshToken);

                        if (response.IsError)
                        {
                            _log.LogWarning("Error refreshing token: {error}", response.Error);
                            return(null);
                        }

                        //set the token to return
                        accessToken = response.AccessToken;

                        var newAccessToken = new UserToken()
                        {
                            Name          = "access_token",
                            Value         = response.AccessToken,
                            UserId        = user.GetUserIdAsGuid(),
                            SiteId        = user.GetUserSiteIdAsGuid(),
                            LoginProvider = "OpenIdConnect"
                        };

                        await _userCommands.UpdateToken(newAccessToken);

                        var newRefreshToken = new UserToken()
                        {
                            Name          = "refresh_token",
                            Value         = response.RefreshToken,
                            UserId        = user.GetUserIdAsGuid(),
                            SiteId        = user.GetUserSiteIdAsGuid(),
                            LoginProvider = "OpenIdConnect"
                        };

                        await _userCommands.UpdateToken(newRefreshToken);

                        var newExpiresAt      = DateTime.UtcNow + TimeSpan.FromSeconds(response.ExpiresIn);
                        var newExpiresAtToken = new UserToken()
                        {
                            Name          = "expires_at",
                            Value         = newExpiresAt.ToString("o", CultureInfo.InvariantCulture),
                            UserId        = user.GetUserIdAsGuid(),
                            SiteId        = user.GetUserSiteIdAsGuid(),
                            LoginProvider = "OpenIdConnect"
                        };


                        await _userCommands.UpdateToken(newExpiresAtToken);

                        await ClearCache(user);
                    }
                    finally
                    {
                        _pendingRefreshTokenRequests.TryRemove(refreshToken, out _);
                    }
                }
            }


            return(accessToken);
        }