public virtual async Task <AmazonS3Client> GetAmazonS3Client(
            AwsBlobProviderConfiguration configuration)
        {
            var region = RegionEndpoint.GetBySystemName(configuration.Region);

            if (configuration.UseCredentials)
            {
                var awsCredentials = GetAwsCredentials(configuration);
                return(awsCredentials == null
                    ? new AmazonS3Client(region)
                    : new AmazonS3Client(awsCredentials, region));
            }

            if (configuration.UseTemporaryCredentials)
            {
                return(new AmazonS3Client(await GetTemporaryCredentialsAsync(configuration), region));
            }

            if (configuration.UseTemporaryFederatedCredentials)
            {
                return(new AmazonS3Client(await GetTemporaryFederatedCredentialsAsync(configuration),
                                          region));
            }

            Check.NotNullOrWhiteSpace(configuration.AccessKeyId, nameof(configuration.AccessKeyId));
            Check.NotNullOrWhiteSpace(configuration.SecretAccessKey, nameof(configuration.SecretAccessKey));

            return(new AmazonS3Client(configuration.AccessKeyId, configuration.SecretAccessKey, configuration.Region));
        }
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.ReplaceConfiguration(ConfigurationHelper.BuildConfiguration(builderAction: builder =>
            {
                builder.AddUserSecrets(UserSecretsId);
            }));

            var configuration   = context.Services.GetConfiguration();
            var accessKeyId     = configuration["Aws:AccessKeyId"];
            var secretAccessKey = configuration["Aws:SecretAccessKey"];
            var region          = configuration["Aws:Region"];

            Configure <AbpBlobStoringOptions>(options =>
            {
                options.Containers.ConfigureAll((containerName, containerConfiguration) =>
                {
                    containerConfiguration.UseAws(aws =>
                    {
                        aws.AccessKeyId                = accessKeyId;
                        aws.SecretAccessKey            = secretAccessKey;
                        aws.Region                     = region;
                        aws.CreateContainerIfNotExists = true;
                        aws.ContainerName              = _randomContainerName;

                        _configuration = aws;
                    });
                });
            });
        }
        protected virtual async Task <SessionAWSCredentials> GetTemporaryFederatedCredentialsAsync(
            AwsBlobProviderConfiguration configuration)
        {
            Check.NotNullOrWhiteSpace(configuration.Name, nameof(configuration.Name));
            Check.NotNullOrWhiteSpace(configuration.Policy, nameof(configuration.Policy));

            var temporaryCredentialsCache = await Cache.GetAsync(configuration.TemporaryCredentialsCacheKey);

            if (temporaryCredentialsCache == null)
            {
                AmazonSecurityTokenServiceClient stsClient;

                if (!configuration.AccessKeyId.IsNullOrEmpty() && !configuration.SecretAccessKey.IsNullOrEmpty())
                {
                    stsClient = new AmazonSecurityTokenServiceClient(configuration.AccessKeyId,
                                                                     configuration.SecretAccessKey);
                }
                else
                {
                    var awsCredentials = GetAwsCredentials(configuration);
                    stsClient = awsCredentials == null
                        ? new AmazonSecurityTokenServiceClient()
                        : new AmazonSecurityTokenServiceClient(awsCredentials);
                }

                using (stsClient)
                {
                    var federationTokenRequest =
                        new GetFederationTokenRequest
                    {
                        DurationSeconds = configuration.DurationSeconds,
                        Name            = configuration.Name,
                        Policy          = configuration.Policy
                    };

                    var federationTokenResponse =
                        await stsClient.GetFederationTokenAsync(federationTokenRequest);

                    var credentials = federationTokenResponse.Credentials;

                    temporaryCredentialsCache =
                        await SetTemporaryCredentialsCache(configuration, credentials);
                }
            }

            var sessionCredentials = new SessionAWSCredentials(
                StringEncryptionService.Decrypt(temporaryCredentialsCache.AccessKeyId),
                StringEncryptionService.Decrypt(temporaryCredentialsCache.SecretAccessKey),
                StringEncryptionService.Decrypt(temporaryCredentialsCache.SessionToken));

            return(sessionCredentials);
        }
        protected virtual AWSCredentials GetAwsCredentials(
            AwsBlobProviderConfiguration configuration)
        {
            if (configuration.ProfileName.IsNullOrWhiteSpace())
            {
                return(null);
            }

            var chain = new CredentialProfileStoreChain(configuration.ProfilesLocation);

            if (chain.TryGetAWSCredentials(configuration.ProfileName, out var awsCredentials))
            {
                return(awsCredentials);
            }

            throw new AmazonS3Exception("Not found aws credentials");
        }
        private async Task <AwsTemporaryCredentialsCacheItem> SetTemporaryCredentialsCache(
            AwsBlobProviderConfiguration configuration,
            Credentials credentials)
        {
            var temporaryCredentialsCache = new AwsTemporaryCredentialsCacheItem(
                StringEncryptionService.Encrypt(credentials.AccessKeyId),
                StringEncryptionService.Encrypt(credentials.SecretAccessKey),
                StringEncryptionService.Encrypt(credentials.SessionToken));

            await Cache.SetAsync(configuration.TemporaryCredentialsCacheKey, temporaryCredentialsCache,
                                 new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(configuration.DurationSeconds - 10)
            });

            return(temporaryCredentialsCache);
        }