Esempio n. 1
0
        public static async Task <Uri> GetUserDelegationSasBlobAsync(this BlobServiceClient self, string containerName, string blobName, BlobSasPermissions permissions = BlobSasPermissions.Read, uint durationMinutes = 10)
        {
            var key = await self.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow.AddMinutes(-5), DateTimeOffset.UtcNow.AddDays(6)); // max is 7 days

            var sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = containerName,
                BlobName          = blobName,
                Resource          = "b",
                StartsOn          = DateTimeOffset.UtcNow.AddMinutes(-5),
                ExpiresOn         = DateTimeOffset.UtcNow.AddMinutes(durationMinutes)
            };

            sasBuilder.SetPermissions(permissions);
            var sasToken = sasBuilder.ToSasQueryParameters(key, self.AccountName).ToString();
            var fullUri  = new UriBuilder()
            {
                Scheme = "https",
                Host   = $"{self.AccountName}.blob.core.windows.net",
                Path   = $"{containerName}/{blobName}",
                Query  = sasToken
            };

            return(fullUri.Uri);
        }
Esempio n. 2
0
        public async Task BlobIdentitySas_AllPermissions()
        {
            // Arrange
            BlobServiceClient oauthService  = GetServiceClient_OauthAccount();
            string            containerName = GetNewContainerName();
            string            blobName      = GetNewBlobName();

            await using DisposingContainer test = await GetTestContainerAsync(containerName : containerName, service : oauthService);

            Response <UserDelegationKey> userDelegationKey = await oauthService.GetUserDelegationKeyAsync(
                startsOn : null,
                expiresOn : Recording.UtcNow.AddHours(1));

            BlobSasBuilder blobSasBuilder = new BlobSasBuilder(
                permissions: BlobSasPermissions.All,
                expiresOn: Recording.UtcNow.AddDays(1))
            {
                BlobContainerName = test.Container.Name,
                BlobName          = blobName
            };

            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(test.Container.Uri)
            {
                BlobName = blobName,
                Sas      = blobSasBuilder.ToSasQueryParameters(userDelegationKey.Value, oauthService.AccountName)
            };

            // Act
            AppendBlobClient appendBlobClient = InstrumentClient(new AppendBlobClient(blobUriBuilder.ToUri(), GetOptions()));
            await appendBlobClient.CreateAsync();
        }
        /// <summary>
        /// The <see cref="GetUserDelegationKeyAsync"/> operation retrieves a
        /// key that can be used to delegate Active Directory authorization to
        /// shared access signatures created with <see cref="Sas.DataLakeSasBuilder"/>.
        /// </summary>
        /// <param name="startsOn">
        /// Start time for the key's validity, with null indicating an
        /// immediate start.  The time should be specified in UTC.
        /// </param>
        /// <param name="expiresOn">
        /// Expiration of the key's validity.  The time should be specified
        /// in UTC.
        /// </param>
        /// <param name="cancellationToken">
        /// Optional <see cref="CancellationToken"/> to propagate
        /// notifications that the operation should be cancelled.
        /// </param>
        /// <returns>
        /// A <see cref="Response{UserDelegationKey}"/> describing
        /// the use delegation key.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure occurs.
        /// </remarks>
        public virtual async Task <Response <UserDelegationKey> > GetUserDelegationKeyAsync(
            DateTimeOffset?startsOn,
            DateTimeOffset expiresOn,
            CancellationToken cancellationToken = default)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(DataLakeServiceClient)}.{nameof(GetUserDelegationKey)}");

            try
            {
                scope.Start();

                Response <Blobs.Models.UserDelegationKey> response = await _blobServiceClient.GetUserDelegationKeyAsync(
                    startsOn,
                    expiresOn,
                    cancellationToken)
                                                                     .ConfigureAwait(false);

                return(Response.FromValue(
                           new UserDelegationKey(response.Value),
                           response.GetRawResponse()));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
Esempio n. 4
0
        private async Task <string> GenerateSasToken(BlobSasBuilder builder, bool useUserDelegation, string storageAccountName, string storageAccountKey)
        {
            var userDelegationStart    = DateTimeOffset.UtcNow.AddHours(-1);
            var userDelegationEnd      = userDelegationStart.AddDays(3);
            var blobSasQueryParameters = useUserDelegation
                ? builder.ToSasQueryParameters(await _serviceClient.GetUserDelegationKeyAsync(userDelegationStart, userDelegationEnd), storageAccountName)
                : builder.ToSasQueryParameters(new StorageSharedKeyCredential(storageAccountName, storageAccountKey));

            return(blobSasQueryParameters.ToString());
        }
Esempio n. 5
0
        public async Task GetUserDelegationKey_Error()
        {
            // Arrange
            BlobServiceClient service = GetServiceClient_SharedKey();

            // Act
            await TestHelper.AssertExpectedExceptionAsync <RequestFailedException>(
                service.GetUserDelegationKeyAsync(startsOn: null, expiresOn: Recording.UtcNow.AddHours(1)),
                e => Assert.AreEqual("AuthenticationFailed", e.ErrorCode));
        }
Esempio n. 6
0
        /// <summary>
        /// Generate a Url to a blob to redirect to with a user delegation sas token.
        /// </summary>
        /// <param name="blobName">Name of blob to redirect to (blob storage name rather than original file name).</param>
        /// <param name="downloadPermissions">Permissions to be applied to the SasBuilder.</param>
        /// <returns></returns>
        public async Task <string> GetRelativeDownloadUrlAsync(string blobName, BlobSasPermissions downloadPermissions, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(blobName))
            {
                throw new ArgumentNullException(nameof(blobName));
            }
            if (string.IsNullOrWhiteSpace(_configurationProvider.FileDownloadEndpoint))
            {
                throw new ArgumentNullException(nameof(_configurationProvider.FileDownloadEndpoint));
            }

            // Set the blob service client
            BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(_configurationProvider.FileDownloadEndpoint), new DefaultAzureCredential());

            // Generate the user delegation key - get from cache if available or add to cache on generation
            var userDelegationKey = await _memoryCache.GetOrCreateAsync(
                Constants.Constants.BlobStorageDownloadUserDelegationKeyCacheKey,
                async cacheEntry =>
            {
                cacheEntry.Priority = CacheItemPriority.High;
                cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(23);

                var azureResponse = await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(1), cancellationToken);
                return(azureResponse.Value);
            });

            if (userDelegationKey != null)
            {
                BlobSasBuilder sasBuilder = new BlobSasBuilder()
                {
                    BlobContainerName = _configurationProvider.FileContainerName,
                    BlobName          = blobName,
                    Resource          = "b",
                    StartsOn          = DateTimeOffset.UtcNow,
                    ExpiresOn         = DateTimeOffset.UtcNow.AddMinutes(40)
                };

                // Specify read and write permissions for the SAS. Pass these in?
                sasBuilder.SetPermissions(downloadPermissions);

                // Add the SAS token to the blob URI.
                BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobServiceClient.Uri)
                {
                    // Set container and blob name
                    BlobContainerName = _configurationProvider.FileContainerName,
                    BlobName          = blobName,
                    // Specify the user delegation key.
                    Sas = sasBuilder.ToSasQueryParameters(userDelegationKey, blobServiceClient.AccountName)
                };

                // Build the blob redirect path required
                return($"{blobUriBuilder.BlobContainerName}/{blobUriBuilder.BlobName}?{blobUriBuilder.Sas}");
            }
            throw new ApplicationException("Unable to generate download token");
        }
Esempio n. 7
0
        public async Task GetUserDelegationKey()
        {
            // Arrange
            BlobServiceClient service = GetServiceClient_OauthAccount();

            // Act
            Response <UserDelegationKey> response = await service.GetUserDelegationKeyAsync(startsOn : null, expiresOn : Recording.UtcNow.AddHours(1));

            // Assert
            Assert.IsNotNull(response.Value);
        }
        private async Task <Uri> GetUserDelegationSasBlobUri(string blobName)
        {
            // Construct the blob endpoint from the account name.
            var blobEndpoint = $"https://{_config["StorageAccount:Name"]}.blob.core.windows.net";

            // Create a new Blob service client with Azure AD credentials.
            var blobClient = new BlobServiceClient(new Uri(blobEndpoint),
                                                   AuthenticationHelper.GetTokenCredential(_config));

            // Get a user delegation key for the Blob service that's valid for 10 minutes.
            // You can use the key to generate any number of shared access signatures over the lifetime of the key.
            UserDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                               DateTimeOffset.UtcNow.AddMinutes(10));

            // Read the key's properties.
            _logger.LogInformation("User delegation key properties:");
            _logger.LogInformation("Key signed start: {0}", key.SignedStartsOn);
            _logger.LogInformation("Key signed expiry: {0}", key.SignedExpiresOn);
            _logger.LogInformation("Key signed object ID: {0}", key.SignedObjectId);
            _logger.LogInformation("Key signed tenant ID: {0}", key.SignedTenantId);
            _logger.LogInformation("Key signed service: {0}", key.SignedService);
            _logger.LogInformation("Key signed version: {0}", key.SignedVersion);

            // Create a SAS token that's valid for one hour.
            var sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = _config["StorageAccount:ContainerName"],
                BlobName          = blobName,
                Resource          = "b",
                StartsOn          = DateTimeOffset.UtcNow,
                ExpiresOn         = DateTimeOffset.UtcNow.AddMinutes(10)
            };

            // Specify write permissions for the SAS.
            sasBuilder.SetPermissions(BlobSasPermissions.Write);

            // Use the key to get the SAS token.
            var sasToken = sasBuilder.ToSasQueryParameters(key, _config["StorageAccount:Name"]).ToString();

            // Construct the full URI, including the SAS token.
            var fullUri = new UriBuilder()
            {
                Scheme = "https",
                Host   = $"{_config["StorageAccount:Name"]}.blob.core.windows.net",
                Path   = $"{_config["StorageAccount:ContainerName"]}/{blobName}",
                Query  = sasToken
            };

            _logger.LogInformation("User delegation SAS URI: {0}", fullUri);

            return(fullUri.Uri);
        }
        private async Task <bool> DoesOAuthWorkAsync()
        {
            TestContext.Error.WriteLine($"Blob Probing OAuth {Process.GetCurrentProcess().Id}");

            try
            {
                for (int i = 0; i < 10; i++)
                {
                    BlobServiceClient serviceClient = new BlobServiceClient(
                        new Uri(TestConfigurations.DefaultTargetOAuthTenant.BlobServiceEndpoint),
                        GetOAuthCredential(TestConfigurations.DefaultTargetOAuthTenant));
                    await serviceClient.GetPropertiesAsync();

                    var containerName   = Guid.NewGuid().ToString();
                    var containerClient = serviceClient.GetBlobContainerClient(containerName);
                    await containerClient.CreateIfNotExistsAsync();

                    try
                    {
                        await containerClient.GetPropertiesAsync();

                        var blobName   = Guid.NewGuid().ToString();
                        var blobClient = containerClient.GetAppendBlobClient(blobName);
                        await blobClient.CreateIfNotExistsAsync();

                        await blobClient.GetPropertiesAsync();

                        var userDelegationKey = await serviceClient.GetUserDelegationKeyAsync(startsOn : null, expiresOn : DateTimeOffset.UtcNow.AddHours(1));

                        var sasBuilder = new BlobSasBuilder(BlobSasPermissions.All, DateTimeOffset.UtcNow.AddHours(1))
                        {
                            BlobContainerName = containerName,
                            BlobName          = blobName,
                        };
                        var sas = sasBuilder.ToSasQueryParameters(userDelegationKey.Value, serviceClient.AccountName).ToString();
                        await new BlobBaseClient(blobClient.Uri, new AzureSasCredential(sas)).GetPropertiesAsync();
                    }
                    finally
                    {
                        await containerClient.DeleteIfExistsAsync();
                    }
                }
            } catch (RequestFailedException e) when(e.Status == 403 && e.ErrorCode == "AuthorizationPermissionMismatch")
            {
                TestContext.Error.WriteLine($"Blob Probing OAuth - not ready {Process.GetCurrentProcess().Id}");
                return(false);
            }
            TestContext.Error.WriteLine($"Blob Probing OAuth - ready {Process.GetCurrentProcess().Id}");
            return(true);
        }
Esempio n. 10
0
        /// <inheritdoc/>
        public async Task <string> GetSasUrlAsync(Uri blobUri, TimeSpan ttl)
        {
            _ = blobUri ?? throw new ArgumentNullException(nameof(blobUri));

            try
            {
                var blobUriBuilder = new BlobUriBuilder(blobUri);

                // Create a SAS token that's valid for the TimeSpan, plus a back-off start for clock skew.
                BlobSasBuilder sasBuilder = new BlobSasBuilder
                {
                    BlobContainerName = blobUriBuilder.BlobContainerName,
                    BlobName          = blobUriBuilder.BlobName,
                    Resource          = "b", // "b" is for blob
                    StartsOn          = DateTimeOffset.UtcNow.AddMinutes(-5),
                    ExpiresOn         = DateTimeOffset.UtcNow + ttl,
                };

                sasBuilder.SetPermissions(BlobSasPermissions.Read); // read permissions only for the SAS.

                var blobServiceClient = new BlobServiceClient(new UriBuilder(blobUriBuilder.Scheme, blobUriBuilder.Host).Uri, _tokenCredential, null);

                var userDelegation = (await blobServiceClient.GetUserDelegationKeyAsync(sasBuilder.StartsOn, sasBuilder.ExpiresOn).ConfigureAwait(false))?.Value;

                if (userDelegation == null)
                {
                    var msg = $@"Unable to get a user delegation key from the Storage service for blob {blobUri}";
                    _log.LogError(msg);
                    throw new Exception(msg);
                }

                var sasToken = sasBuilder.ToSasQueryParameters(userDelegation, blobUriBuilder.AccountName);
                blobUriBuilder.Sas = sasToken;

                // Construct the full URI, including the SAS token.
                return(blobUriBuilder.ToUri().ToString());
            }
            catch (RequestFailedException e)
            {
                var msg = $@"Unable to get a user delegation key from the Storage service for blob {blobUri}";
                _log.LogError(msg);
                throw new Exception(msg, e);
            }
            catch (Exception e)
            {
                var msg = $@"Failed to generate the SAS url for blob {blobUri}";
                _log.LogError(msg);
                throw new Exception(msg, e);
            }
        }
        public virtual async Task <Response <UserDelegationKey> > GetUserDelegationKeyAsync(
            DateTimeOffset?start,
            DateTimeOffset expiry,
            CancellationToken cancellationToken = default)
        {
            Response <Blobs.Models.UserDelegationKey> response = await _blobServiceClient.GetUserDelegationKeyAsync(
                start,
                expiry,
                cancellationToken)
                                                                 .ConfigureAwait(false);

            return(Response.FromValue(
                       new UserDelegationKey(response.Value),
                       response.GetRawResponse()));
        }
Esempio n. 12
0
        public async Task GetUserDelegationKey_ArgumentException()
        {
            // Arrange
            BlobServiceClient service = GetServiceClient_OauthAccount();

            // Act
            await TestHelper.AssertExpectedExceptionAsync <ArgumentException>(
                service.GetUserDelegationKeyAsync(
                    startsOn: null,
                    // ensure the time used is not UTC, as DateTimeOffset.Now could actually be UTC based on OS settings
                    // Use a custom time zone so we aren't dependent on OS having specific standard time zone.
                    expiresOn: TimeZoneInfo.ConvertTime(
                        Recording.Now.AddHours(1),
                        TimeZoneInfo.CreateCustomTimeZone("Storage Test Custom Time Zone", TimeSpan.FromHours(-3), "CTZ", "CTZ"))),
                e => Assert.AreEqual("expiresOn must be UTC", e.Message));;
        }
Esempio n. 13
0
        private async static Task <Uri> GetUserDelegationSasBlob(string containerName, string blobName)
        {
            // Construct the blob endpoint from the account name.
            string blobEndpoint = string.Format("https://{0}.blob.core.windows.net", Settings.StorageAccount);


            var credential = new ClientSecretCredential(
                Settings.TenantId,
                Settings.ClientId,
                Settings.ClientSecret,
                new TokenCredentialOptions());

            // Create a new Blob service client with Azure AD credentials.
            BlobServiceClient blobClient = new BlobServiceClient(new Uri(blobEndpoint), credential);

            // Get a user delegation key for the Blob service that's valid for seven days.
            // You can use the key to generate any number of shared access signatures over the lifetime of the key.
            UserDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(7));

            // Create a SAS token that's valid for one hour.
            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = containerName,
                BlobName          = blobName,
                Resource          = "b",
                StartsOn          = DateTimeOffset.UtcNow,
                ExpiresOn         = DateTimeOffset.UtcNow.AddHours(1)
            };

            // Specify read permissions for the SAS.
            sasBuilder.SetPermissions(BlobSasPermissions.Read);

            // Use the key to get the SAS token.
            string sasToken = sasBuilder.ToSasQueryParameters(key, Settings.StorageAccount).ToString();

            // Construct the full URI, including the SAS token.
            UriBuilder fullUri = new UriBuilder()
            {
                Scheme = "https",
                Host   = string.Format("{0}.blob.core.windows.net", Settings.StorageAccount),
                Path   = string.Format("{0}/{1}", containerName, blobName),
                Query  = sasToken
            };

            return(fullUri.Uri);
        }
        public async Task <Uri> GetSharedAccessUriAsync(string blobName, string directoryRelativeAddress = null, BlobSasPermissions permissions = BlobSasPermissions.Read, DateTimeOffset?startTime = null, DateTimeOffset?expiryTime = null, CancellationToken cancellationToken = default)
        {
            ArgCheck.NotNullOrEmpty(nameof(blobName), blobName);

            directoryRelativeAddress ??= _defaultDirectoryRelativeAddress;
            startTime ??= DateTimeOffset.UtcNow.AddMinutes(-5);
            expiryTime ??= DateTimeOffset.UtcNow.Add(_defaultSharedAccessDuration);
            var blobClient = GetBlobClient(blobName, directoryRelativeAddress);

            var sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = blobClient.BlobContainerName,
                BlobName          = blobClient.Name,
                Resource          = "b",
                StartsOn          = startTime.Value,
                ExpiresOn         = expiryTime.Value,
                Protocol          = SasProtocol.Https,
            };

            sasBuilder.SetPermissions(permissions);

            if (blobClient.CanGenerateSasUri)
            {
                return(CleanUpUri(blobClient.GenerateSasUri(sasBuilder)));
            }

            if (_storageSharedKeyCredential != null)
            {
                return(CleanUpUri(new BlobUriBuilder(blobClient.Uri)
                {
                    Sas = sasBuilder.ToSasQueryParameters(_storageSharedKeyCredential),
                }.ToUri()));
            }

            if (_useManagedIdentity)
            {
                var userDelegationKey = (await _accountClient.GetUserDelegationKeyAsync(null, expiryTime.Value, cancellationToken).ConfigureAwait(false)).Value;

                return(CleanUpUri(new BlobUriBuilder(blobClient.Uri)
                {
                    Sas = sasBuilder.ToSasQueryParameters(userDelegationKey, blobClient.AccountName),
                }.ToUri()));
            }

            throw new InvalidOperationException("Must use Shared Account Key or Token Credentials (including Managed Identity) assigned the Storage Blob Delegator role to generate a Shared Access Signature (SAS).");
        }
Esempio n. 15
0
        private static async Task <Uri> GetUserDelegationSasBlob(TokenAcquisitionTokenCredential tokenCredential, string blobName)
        {
            // BlobServiceClient blobServiceClient =
            //     blobClient.GetParentBlobContainerClient().GetParentBlobServiceClient();
            Uri blobUri           = new Uri("https://cshuicantonresturant.blob.core.windows.net");
            var blobServiceClient = new BlobServiceClient(blobUri, tokenCredential);
            var containerClient   = blobServiceClient.GetBlobContainerClient("testclient");
            var blobClient        = containerClient.GetBlobClient(blobName);
            // Get a user delegation key for the Blob service that's valid for 7 days.
            // You can use the key to generate any number of shared access signatures
            // over the lifetime of the key.
            var userDelegationKey =
                await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                  DateTimeOffset.UtcNow.AddDays(7));

            // Create a SAS token that's also valid for 7 days.
            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = blobClient.BlobContainerName,
                BlobName          = blobClient.Name,
                Resource          = "b",
                StartsOn          = DateTimeOffset.UtcNow,
                ExpiresOn         = DateTimeOffset.UtcNow.AddDays(7)
            };

            // Specify read and write permissions for the SAS.
            sasBuilder.SetPermissions(BlobSasPermissions.Read |
                                      BlobSasPermissions.Write);

            // Add the SAS token to the blob URI.
            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
            {
                // Specify the user delegation key.
                Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
                                                      blobServiceClient.AccountName)
            };

            Console.WriteLine("Blob user delegation SAS URI: {0}", blobUriBuilder);
            Console.WriteLine();
            return(blobUriBuilder.ToUri());
        }
        public async Task <string> GetFileUrl(string fileName)
        {
            //BlobClient blobClient = containerClient.GetBlobClient(fileName);
            //if (! await blobClient.ExistsAsync())
            //    return null;

            //return blobClient.Uri.AbsoluteUri;

            ////var key = await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
            ////                                                       DateTimeOffset.UtcNow.AddDays(7));
            //string blobEndpoint = string.Format("https://{0}.blob.core.windows.net", ACCOUNT_NAME);
            string            blobEndpoint = END_POINT;
            BlobServiceClient blobClient   = new BlobServiceClient(new Uri(blobEndpoint),
                                                                   new DefaultAzureCredential());

            UserDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                               DateTimeOffset.UtcNow.AddDays(7));

            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = CONTAINER_NAME,
                BlobName          = fileName,
                Resource          = "b",
                StartsOn          = DateTimeOffset.UtcNow,
                ExpiresOn         = DateTimeOffset.UtcNow.AddHours(1)
            };

            sasBuilder.SetPermissions(BlobAccountSasPermissions.Read);

            string sasToken = sasBuilder.ToSasQueryParameters(key, ACCOUNT_NAME).ToString();

            UriBuilder fullUri = new UriBuilder()
            {
                Scheme = "https",
                Host   = /*string.Format("{0}.blob.core.windows.net", accountName)*/ END_POINT,
                Path   = string.Format("{0}/{1}", CONTAINER_NAME, fileName),
                Query  = sasToken
            };

            return(fullUri.Uri.AbsoluteUri);
        }
Esempio n. 17
0
        // </Snippet_ReadBlobWithSasAsync>

        #endregion

        #region

        // <Snippet_GetUserDelegationSasContainer>
        async static Task <Uri> GetUserDelegationSasContainer(BlobContainerClient blobContainerClient)
        {
            BlobServiceClient blobServiceClient = blobContainerClient.GetParentBlobServiceClient();

            // Get a user delegation key for the Blob service that's valid for seven days.
            // You can use the key to generate any number of shared access signatures
            // over the lifetime of the key.
            Azure.Storage.Blobs.Models.UserDelegationKey userDelegationKey =
                await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                  DateTimeOffset.UtcNow.AddDays(7));

            // Create a SAS token that's also valid for seven days.
            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = blobContainerClient.Name,
                Resource          = "c",
                StartsOn          = DateTimeOffset.UtcNow,
                ExpiresOn         = DateTimeOffset.UtcNow.AddDays(7)
            };

            // Specify racwl permissions for the SAS.
            sasBuilder.SetPermissions(
                BlobContainerSasPermissions.Read |
                BlobContainerSasPermissions.Add |
                BlobContainerSasPermissions.Create |
                BlobContainerSasPermissions.Write |
                BlobContainerSasPermissions.List
                );

            // Add the SAS token to the container URI.
            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobContainerClient.Uri)
            {
                // Specify the user delegation key.
                Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
                                                      blobServiceClient.AccountName)
            };

            Console.WriteLine("Container user delegation SAS URI: {0}", blobUriBuilder);
            Console.WriteLine();
            return(blobUriBuilder.ToUri());
        }
Esempio n. 18
0
        public async Task BlobVersionIdentitySas_AllPermissions()
        {
            // Arrange
            BlobServiceClient oauthService  = GetServiceClient_OauthAccount();
            string            containerName = GetNewContainerName();
            string            blobName      = GetNewBlobName();

            await using DisposingContainer test = await GetTestContainerAsync(containerName : containerName, service : oauthService);

            Response <UserDelegationKey> userDelegationKey = await oauthService.GetUserDelegationKeyAsync(
                startsOn : null,
                expiresOn : Recording.UtcNow.AddHours(1));

            AppendBlobClient           blob           = InstrumentClient(test.Container.GetAppendBlobClient(blobName));
            Response <BlobContentInfo> createResponse = await blob.CreateAsync();

            IDictionary <string, string> metadata         = BuildMetadata();
            Response <BlobInfo>          metadataResponse = await blob.SetMetadataAsync(metadata);

            BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
            {
                ExpiresOn         = Recording.UtcNow.AddDays(1),
                BlobContainerName = test.Container.Name,
                BlobName          = blobName,
                BlobVersionId     = createResponse.Value.VersionId
            };

            blobSasBuilder.SetPermissions(BlobVersionSasPermissions.All);

            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blob.Uri)
            {
                VersionId = createResponse.Value.VersionId,
                Sas       = blobSasBuilder.ToSasQueryParameters(userDelegationKey.Value, oauthService.AccountName)
            };

            // Act
            AppendBlobClient sasBlobClient = InstrumentClient(new AppendBlobClient(blobUriBuilder.ToUri(), GetOptions()));
            await sasBlobClient.DeleteAsync();
        }
Esempio n. 19
0
        private async Task <string> GenerateSasUrl(string containerName, string blobName)
        {
            var storageAccount = Environment.GetEnvironmentVariable("AZURE_STORAGE_ACCOUNT_NAME");

            // Create a BlobServiceClient that will authenticate through Active Directory
            Uri accountUri           = new Uri(String.Format("https://{0}.blob.core.windows.net/", storageAccount));
            BlobServiceClient client = new BlobServiceClient(accountUri, new DefaultAzureCredential());

            var containerClient = client.GetBlobContainerClient(containerName);

            // Create a SAS token that's valid for one hour.
            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = containerName,
                BlobName          = blobName,
                Resource          = "b",
                StartsOn          = DateTimeOffset.UtcNow,
                ExpiresOn         = DateTimeOffset.UtcNow.AddHours(1)
            };

            // Specify read permissions for the SAS.
            sasBuilder.SetPermissions(BlobSasPermissions.Read);

            UserDelegationKey key = await client.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                           DateTimeOffset.UtcNow.AddDays(7));

            string sasToken = sasBuilder.ToSasQueryParameters(key, storageAccount).ToString();

            // Construct the full URI, including the SAS token.
            UriBuilder fullUri = new UriBuilder()
            {
                Scheme = "https",
                Host   = string.Format("{0}.blob.core.windows.net", storageAccount),
                Path   = string.Format("{0}/{1}", containerName, blobName),
                Query  = sasToken
            };

            return(fullUri.ToString());
        }
Esempio n. 20
0
        public async Task BlobSnapshotIdentitySas_AllPermissions()
        {
            // Arrange
            BlobServiceClient oauthService  = GetServiceClient_OauthAccount();
            string            containerName = GetNewContainerName();
            string            blobName      = GetNewBlobName();

            await using DisposingContainer test = await GetTestContainerAsync(containerName : containerName, service : oauthService);

            Response <UserDelegationKey> userDelegationKey = await oauthService.GetUserDelegationKeyAsync(
                startsOn : null,
                expiresOn : Recording.UtcNow.AddHours(1));

            AppendBlobClient blob = InstrumentClient(test.Container.GetAppendBlobClient(blobName));
            await blob.CreateAsync();

            Response <BlobSnapshotInfo> snapshotResponse = await blob.CreateSnapshotAsync();

            BlobSasBuilder blobSasBuilder = new BlobSasBuilder()
            {
                ExpiresOn         = Recording.UtcNow.AddDays(1),
                BlobContainerName = test.Container.Name,
                BlobName          = blobName,
                Snapshot          = snapshotResponse.Value.Snapshot
            };

            blobSasBuilder.SetPermissions(SnapshotSasPermissions.All);

            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blob.Uri)
            {
                Snapshot = snapshotResponse.Value.Snapshot,
                Sas      = blobSasBuilder.ToSasQueryParameters(userDelegationKey.Value, oauthService.AccountName)
            };

            // Act
            AppendBlobClient sasBlobClient = InstrumentClient(new AppendBlobClient(blobUriBuilder.ToUri(), GetOptions()));
            await sasBlobClient.GetPropertiesAsync();
        }
        public async Task BlobSasBuilder_PreauthorizedAgentObjectId()
        {
            // Arrange
            BlobServiceClient oauthService           = GetServiceClient_OauthAccount();
            string            containerName          = GetNewContainerName();
            string            preauthorizedAgentGuid = Recording.Random.NewGuid().ToString();

            await using DisposingContainer test = await GetTestContainerAsync(service : oauthService, containerName : containerName);

            // Arrange
            Response <UserDelegationKey> userDelegationKey = await oauthService.GetUserDelegationKeyAsync(
                startsOn : null,
                expiresOn : Recording.UtcNow.AddHours(1));

            BlobSasBuilder BlobSasBuilder = new BlobSasBuilder
            {
                StartsOn                   = Recording.UtcNow.AddHours(-1),
                ExpiresOn                  = Recording.UtcNow.AddHours(1),
                BlobContainerName          = containerName,
                PreauthorizedAgentObjectId = preauthorizedAgentGuid
            };

            BlobSasBuilder.SetPermissions(BlobSasPermissions.All);

            BlobUriBuilder BlobUriBuilder = new BlobUriBuilder(test.Container.Uri)
            {
                Sas = BlobSasBuilder.ToSasQueryParameters(userDelegationKey, test.Container.AccountName)
            };

            BlobContainerClient containerClient = InstrumentClient(new BlobContainerClient(BlobUriBuilder.ToUri(), GetOptions()));

            // Act
            BlobClient blobClient = containerClient.GetBlobClient(GetNewBlobName());
            await blobClient.UploadAsync(new MemoryStream());

            await blobClient.ExistsAsync();
        }
        public async Task BlobSasBuilder_CorrelationId()
        {
            // Arrange
            BlobServiceClient oauthService  = GetServiceClient_OauthAccount();
            string            containerName = GetNewContainerName();

            await using DisposingContainer test = await GetTestContainerAsync(service : oauthService, containerName : containerName);

            // Arrange
            Response <UserDelegationKey> userDelegationKey = await oauthService.GetUserDelegationKeyAsync(
                startsOn : null,
                expiresOn : Recording.UtcNow.AddHours(1));

            BlobSasBuilder blobSasBuilder = new BlobSasBuilder
            {
                StartsOn          = Recording.UtcNow.AddHours(-1),
                ExpiresOn         = Recording.UtcNow.AddHours(1),
                BlobContainerName = containerName,
                CorrelationId     = Recording.Random.NewGuid().ToString()
            };

            blobSasBuilder.SetPermissions(BlobSasPermissions.All);

            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(test.Container.Uri)
            {
                Sas = blobSasBuilder.ToSasQueryParameters(userDelegationKey, test.Container.AccountName)
            };

            BlobContainerClient containerClient = InstrumentClient(new BlobContainerClient(blobUriBuilder.ToUri(), GetOptions()));

            // Act
            await foreach (BlobItem pathItem in containerClient.GetBlobsAsync())
            {
                // Just make sure the call succeeds.
            }
        }
Esempio n. 23
0
        public async Task <string> GetBlobSasToken(string url, string userAssignedClientId)
        {
            var uri        = new Uri(url);
            var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions {
                ManagedIdentityClientId = userAssignedClientId
            });
            var blobClient  = new BlobServiceClient(new Uri($"https://{uri.Host}"), credential);
            var accountName = blobClient.AccountName;

            Console.WriteLine(uri.Segments[1].Trim('/'));

            var delegationKey = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(7));

            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = uri.Segments[1].Trim('/'),
                BlobName          = uri.Segments[2],
                Resource          = "b",
                StartsOn          = DateTimeOffset.UtcNow,
                ExpiresOn         = DateTimeOffset.UtcNow.AddHours(1)
            };

            sasBuilder.SetPermissions(BlobSasPermissions.Read);
            Console.WriteLine(sasBuilder.Permissions);
            var sasQueryParams = sasBuilder.ToSasQueryParameters(delegationKey, accountName).ToString();

            UriBuilder sasUri = new UriBuilder()
            {
                Scheme = "https",
                Host   = uri.Host,
                Path   = uri.AbsolutePath,
                Query  = sasQueryParams
            };

            return(sasUri.ToString());
        }
Esempio n. 24
0
        async Task <Uri> IAzureBlobStoreClient.GenerateEphemeralDownloadLink(string containerName, string blobName, string blobVersion, string publicFacingBlobName, CancellationToken cancellationToken)
        {
            // We will secure the link by creating a user delegate sas token signed by the managed identity of this application, thus
            // only the intersection of allowed permissions are applicable.   In this case, we only want to assign the read
            // permission to the token, and for such access to be limited to a set period of time after which the token will expire
            //
            // If running local, note that the azure credentials resolved are those you are logged in as (for example the Visual Studio
            // azure account)

            if (string.IsNullOrWhiteSpace(containerName))
            {
                throw new ArgumentNullException(nameof(containerName));
            }
            if (string.IsNullOrWhiteSpace(blobName))
            {
                throw new ArgumentNullException(nameof(blobName));
            }
            if (string.IsNullOrWhiteSpace(blobVersion))
            {
                throw new ArgumentNullException(nameof(blobVersion));
            }
            if (string.IsNullOrWhiteSpace(publicFacingBlobName))
            {
                throw new ArgumentNullException(nameof(publicFacingBlobName));
            }

            cancellationToken.ThrowIfCancellationRequested();

            var managedIdentityCredential = new DefaultAzureCredential();

            var blobClientOptions = GetBlobClientOptions(_geoRedundantServiceUrl);

            var blobServiceClient = new BlobServiceClient(_primaryServiceUrl, managedIdentityCredential, blobClientOptions);

            var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);

            var blobClient = blobContainerClient.GetBlobClient(blobName).WithVersion(blobVersion);

            var tokenStartsOn = _systemClock.UtcNow;

            var tokenExpiresOn = tokenStartsOn.AddMinutes(TOKEN_SAS_TIMEOUT_IN_MINUTES);

            var fileInfo = new FileInfo(publicFacingBlobName);

            var setContentDisposition = !string.IsNullOrWhiteSpace(fileInfo.Extension);

            var userDelegationKey = await _memoryCache.GetOrCreateAsync(
                $"{nameof(AzureBlobStoreClient)}:UserDelegationKey",
                async cacheEntry =>
            {
                cacheEntry.Priority = CacheItemPriority.High;
                cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1);

                try
                {
                    var azureResponse = await blobServiceClient.GetUserDelegationKeyAsync(tokenStartsOn, tokenExpiresOn, cancellationToken);

                    return(azureResponse.Value);
                }
                catch (RequestFailedException ex)
                {
                    _logger?.LogError(ex, "Unable to access the storage endpoint to generate a user delegation key: '{StatusCode} {StatusCodeName}'", ex.Status, Enum.Parse(typeof(HttpStatusCode), Convert.ToString(ex.Status, CultureInfo.InvariantCulture)));

                    throw;
                }
            });

            var readOnlyPermission = BlobSasPermissions.Read;

            var blobSasBuilder = new BlobSasBuilder(readOnlyPermission, tokenExpiresOn)
            {
                BlobContainerName  = blobContainerClient.Name,
                BlobName           = blobClient.Name,
                BlobVersionId      = blobVersion,
                Resource           = "b",
                StartsOn           = tokenStartsOn,
                ExpiresOn          = tokenExpiresOn,
                Protocol           = SasProtocol.Https,
                ContentDisposition = setContentDisposition ? $"attachment; filename*=UTF-8''{Uri.EscapeDataString(publicFacingBlobName)}" : default
                                     //PreauthorizedAgentObjectId = set this if we use AAD to authenticate our users,
            };

            var blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
            {
                Sas = blobSasBuilder.ToSasQueryParameters(userDelegationKey, blobServiceClient.AccountName)
            };

            var uri = blobUriBuilder.ToUri();

            return(uri);
        }
Esempio n. 25
0
 private async Task UpdateDelegationKey()
 {
     _delegationKey = await _serviceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                     DateTimeOffset.UtcNow.AddDays(7));
 }
Esempio n. 26
0
        private async Task <bool> DoesOAuthWorkAsync()
        {
            TestContext.Error.WriteLine($"Datalake Probing OAuth {Process.GetCurrentProcess().Id}");

            try
            {
                for (int i = 0; i < 10; i++)
                {
                    // Check flat account. For some reason we observe failures if that one doesn't work before we start datalake run.
                    {
                        BlobServiceClient serviceClient = new BlobServiceClient(
                            new Uri(TestConfigurations.DefaultTargetOAuthTenant.BlobServiceEndpoint),
                            GetOAuthCredential(TestConfigurations.DefaultTargetOAuthTenant));
                        await serviceClient.GetPropertiesAsync();

                        var containerName   = Guid.NewGuid().ToString();
                        var containerClient = serviceClient.GetBlobContainerClient(containerName);
                        await containerClient.CreateIfNotExistsAsync();

                        try
                        {
                            await containerClient.GetPropertiesAsync();

                            var blobName   = Guid.NewGuid().ToString();
                            var blobClient = containerClient.GetAppendBlobClient(blobName);
                            await blobClient.CreateIfNotExistsAsync();

                            await blobClient.GetPropertiesAsync();

                            var userDelegationKey = await serviceClient.GetUserDelegationKeyAsync(startsOn : null, expiresOn : DateTimeOffset.UtcNow.AddHours(1));

                            var sasBuilder = new BlobSasBuilder(BlobSasPermissions.All, DateTimeOffset.UtcNow.AddHours(1))
                            {
                                BlobContainerName = containerName,
                                BlobName          = blobName,
                            };
                            var sas = sasBuilder.ToSasQueryParameters(userDelegationKey.Value, serviceClient.AccountName).ToString();
                            await new BlobBaseClient(blobClient.Uri, new AzureSasCredential(sas)).GetPropertiesAsync();
                        }
                        finally
                        {
                            await containerClient.DeleteIfExistsAsync();
                        }
                    }

                    // Check hierarchical account.
                    {
                        DataLakeServiceClient serviceClient = new DataLakeServiceClient(
                            new Uri(TestConfigurations.DefaultTargetHierarchicalNamespaceTenant.BlobServiceEndpoint),
                            GetOAuthCredential(TestConfigurations.DefaultTargetHierarchicalNamespaceTenant));
                        await serviceClient.GetPropertiesAsync();

                        var fileSystemName   = Guid.NewGuid().ToString();
                        var fileSystemClient = serviceClient.GetFileSystemClient(fileSystemName);
                        await fileSystemClient.CreateIfNotExistsAsync();

                        try
                        {
                            var directoryName   = Guid.NewGuid().ToString();
                            var directoryClient = fileSystemClient.GetDirectoryClient(directoryName);
                            await directoryClient.CreateIfNotExistsAsync();

                            await directoryClient.GetPropertiesAsync();

                            var fileName   = Guid.NewGuid().ToString();
                            var fileClient = directoryClient.GetFileClient(fileName);
                            await fileClient.CreateIfNotExistsAsync();

                            await fileClient.GetPropertiesAsync();

                            // call some APIs that talk to DFS endoint as well.
                            await fileClient.AppendAsync(new MemoryStream(new byte[] { 1 }), 0);

                            await fileClient.GetAccessControlAsync();

                            var userDelegationKey = await serviceClient.GetUserDelegationKeyAsync(startsOn : null, expiresOn : DateTimeOffset.UtcNow.AddHours(1));

                            var sasBuilder = new DataLakeSasBuilder(DataLakeSasPermissions.All, DateTimeOffset.UtcNow.AddHours(1))
                            {
                                FileSystemName = fileSystemName,
                                Path           = fileClient.Path,
                            };
                            var sas = sasBuilder.ToSasQueryParameters(userDelegationKey.Value, serviceClient.AccountName).ToString();
                            await new DataLakeFileClient(fileClient.Uri, new AzureSasCredential(sas)).GetPropertiesAsync();
                        }
                        finally
                        {
                            await fileSystemClient.DeleteIfExistsAsync();
                        }
                    }
                }
            }
            catch (RequestFailedException e) when(e.Status == 403 && e.ErrorCode == "AuthorizationPermissionMismatch")
            {
                TestContext.Error.WriteLine($"Datalake Probing OAuth - not ready {Process.GetCurrentProcess().Id}");
                return(false);
            }
            TestContext.Error.WriteLine($"Datalake Probing OAuth - ready {Process.GetCurrentProcess().Id}");
            return(true);
        }