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); }
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(); } }
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()); }
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)); }
/// <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"); }
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); }
/// <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())); }
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));; }
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)."); }
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); }
// </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()); }
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(); }
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()); }
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. } }
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()); }
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); }
private async Task UpdateDelegationKey() { _delegationKey = await _serviceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(7)); }
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); }