Esempio n. 1
0
        /// <inheritdoc/>
        public async Task <TokenResultModel> GetTokenForAsync(string resource,
                                                              IEnumerable <string> scopes)
        {
            var exceptions = new List <Exception>();

            foreach (var config in _config.Query(resource, AuthProvider.AuthService))
            {
                if (string.IsNullOrEmpty(config.ClientSecret))
                {
                    continue;
                }
                try {
                    var client   = Http.CreateClient("token_client");
                    var response = await client.RequestClientCredentialsTokenAsync(
                        new ClientCredentialsTokenRequest {
                        Address      = $"{config.GetAuthorityUrl()}/connect/token",
                        ClientId     = config.ClientId,
                        ClientSecret = config.ClientSecret
                    });

                    if (response.IsError)
                    {
                        _logger.Error("Error {error} aquiring token for {resource} with {config}",
                                      response.Error, resource, config.GetName());
                        return(null);
                    }
                    var result = JwtSecurityTokenEx.Parse(response.AccessToken);
                    _logger.Information(
                        "Successfully acquired token for {resource} with {config}.",
                        resource, config.GetName());
                    return(result);
                }
                catch (Exception exc) {
                    _logger.Debug(exc, "Failed to get token for {resource} using {config}",
                                  resource, config.GetName());
                    exceptions.Add(exc);
                }
            }
            if (exceptions.Count != 0)
            {
                throw new AggregateException(exceptions);
            }
            return(null);
        }
Esempio n. 2
0
        /// <inheritdoc/>
        public async Task <TokenResultModel> GetTokenForAsync(string resource,
                                                              IEnumerable <string> scopes)
        {
            var exceptions = new List <Exception>();

            foreach (var(config, provider) in Get(resource))
            {
                try {
                    var token = await provider.KeyVaultTokenCallback(
                        config.GetAuthorityUrl(true), config.GetAudience(scopes),
                        config.GetScopeNames(scopes)?.FirstOrDefault());

                    if (token == null)
                    {
                        return(null);
                    }
                    var result = JwtSecurityTokenEx.Parse(token);
                    if (result.ExpiresOn < DateTime.UtcNow)
                    {
                        return(null);
                    }
                    _logger.Information(
                        "Successfully acquired token for {resource} with {config}.",
                        resource, config.GetName());
                    return(result);
                }
                catch (Exception ex) {
                    _logger.Debug(ex,
                                  "Failed to retrieve token for {resource} using {config}",
                                  resource, config.GetName());
                    exceptions.Add(ex);
                    continue;
                }
            }
            if (exceptions.Count != 0)
            {
                throw new AggregateException(exceptions);
            }
            return(null);
        }
Esempio n. 3
0
        /// <summary>
        /// Helper to get token from cache
        /// </summary>
        /// <returns></returns>
        private async Task <TokenResultModel> GetTokenFromCacheAsync(string resource,
                                                                     IEnumerable <string> scopes)
        {
            var cached = await _cache.GetAsync(GetKey(resource));

            if (cached != null)
            {
                var token = JwtSecurityTokenEx.Parse(Encoding.UTF8.GetString(cached));
                if (token.ExpiresOn >= DateTimeOffset.UtcNow + TimeSpan.FromSeconds(30))
                {
                    if (scopes != null)
                    {
                        // TODO: Check token has all scope is part of the token
                        if (!scopes.All(scope => string.IsNullOrEmpty(scope)))
                        {
                            return(null);
                        }
                    }
                    return(token);
                }
            }
            return(null);
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public async Task <TokenResultModel> GetTokenForAsync(string resource,
                                                              IEnumerable <string> scopes)
        {
            const string kAccessTokenKey = "access_token";

            if (_ctx.HttpContext == null)
            {
                return(null);
            }
            string token = null;

            if (_providers == null)
            {
                token = await _ctx.HttpContext.GetTokenAsync(kAccessTokenKey);
            }
            else
            {
                foreach (var provider in _providers)
                {
                    token = await _ctx.HttpContext.GetTokenAsync(provider, kAccessTokenKey);

                    if (token != null)
                    {
                        break; // Use first found token
                    }
                }
            }
            if (string.IsNullOrEmpty(token))
            {
                return(null);
            }
            var result = JwtSecurityTokenEx.Parse(token);

            result.Cached = true; // Already cached as part of context
            return(result);
        }
        /// <inheritdoc/>
        public async Task <TokenResultModel> GetTokenForAsync(string resource,
                                                              IEnumerable <string> scopes)
        {
            var user = _ctx.HttpContext?.User;

            if (user == null)
            {
                return(null);
            }

            var schemes = await _schemes.GetAllSchemesAsync();

            if (!schemes.Any(s => s.Name == AuthProvider.AuthService))
            {
                return(null);
            }

            if (!user.Identity.IsAuthenticated)
            {
                _logger.Debug("User is not authenticated.");
                return(null);
            }
            var userName = user.FindFirst(JwtClaimTypes.Name)?.Value ??
                           user.FindFirst(JwtClaimTypes.Subject)?.Value ?? "unknown";

            var(accessToken, expiration, refreshToken) = await GetTokenFromCacheAsync();

            if (refreshToken == null)
            {
                _logger.Debug("No token data found in user token store.");
                return(null);
            }

            var dtRefresh = expiration.Value.Subtract(TimeSpan.FromMinutes(1));

            if (dtRefresh >= _clock.UtcNow)
            {
                // Token still valid - use it.
                var token = JwtSecurityTokenEx.Parse(accessToken);
                token.Cached = true;
                return(token);
            }

            var exceptions = new List <Exception>();

            foreach (var config in _config.Query(resource, AuthProvider.AuthService))
            {
                try {
                    _logger.Debug("Token for user {user} needs refreshing.", userName);
                    try {
                        accessToken = await kRequests.GetOrAdd(refreshToken, t => {
                            return(new Lazy <Task <string> >(async() => {
                                var refreshed = await RefreshUserAccessTokenAsync(t, config);
                                return refreshed.AccessToken;
                            }));
                        }).Value;

                        var token = JwtSecurityTokenEx.Parse(accessToken);
                        token.Cached = true;
                        _logger.Information(
                            "Successfully refreshed token for {resource} with {config}.",
                            resource, config.GetName());
                        return(token);
                    }
                    finally {
                        kRequests.TryRemove(refreshToken, out _);
                    }
                }
                catch (Exception e) {
                    _logger.Debug(e, "Failed to get token for {resource} with {config}.",
                                  resource, config.GetName());
                    exceptions.Add(e);
                    continue;
                }
            }
            if (exceptions.Count != 0)
            {
                throw new AggregateException(exceptions);
            }
            return(null);
        }