Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Storage] SAS Credential in Storage. #17646

Merged
merged 32 commits into from
Jan 11, 2021
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a4c5ebc
Add AzureSasCredential
kasobol-msft Dec 17, 2020
5fdb953
corner case.
kasobol-msft Dec 17, 2020
bb719f2
Merge remote-tracking branch 'upstream/master' into sas-credential
kasobol-msft Dec 17, 2020
61c3839
api.
kasobol-msft Dec 17, 2020
2504f78
core as project ref (todo undo this)
kasobol-msft Dec 18, 2020
fa6536d
first client.
kasobol-msft Dec 18, 2020
2bccb52
hack azure core in webjobs for now.
kasobol-msft Dec 18, 2020
bd20b54
api.
kasobol-msft Dec 18, 2020
fd86385
constructors.
kasobol-msft Dec 18, 2020
4b38c1e
blob tests.
kasobol-msft Dec 18, 2020
8becf87
datalake tests.
kasobol-msft Dec 18, 2020
e117feb
share tests + take out sas on share and service clients as there isn'…
kasobol-msft Dec 18, 2020
f35672e
queues tests.
kasobol-msft Dec 18, 2020
454586c
well that works. nvm.
kasobol-msft Dec 18, 2020
1740da6
remarks.
kasobol-msft Dec 28, 2020
d68dd4e
error message.
kasobol-msft Dec 28, 2020
0f83c9b
predicate shouldn't be optional.
kasobol-msft Dec 28, 2020
0aa98f0
merge master
kasobol-msft Jan 5, 2021
01c538b
post-merge tweaks.
kasobol-msft Jan 5, 2021
730a3b5
message about right UriBuilder.
kasobol-msft Jan 5, 2021
31d9c96
added uri validation.
kasobol-msft Jan 5, 2021
3389e39
changelog.
kasobol-msft Jan 5, 2021
39d059b
user delegation sas change.
kasobol-msft Jan 5, 2021
43dcaf6
batch.
kasobol-msft Jan 5, 2021
f8ab972
merge master.
kasobol-msft Jan 5, 2021
e33ca4c
this test doesn't work well in playback mode.
kasobol-msft Jan 5, 2021
f108a76
pr feedback.
kasobol-msft Jan 6, 2021
c35d5e2
comments.
kasobol-msft Jan 6, 2021
5975ee9
validation.
kasobol-msft Jan 6, 2021
f68c029
Merge remote-tracking branch 'upstream/master' into sas-credential-in…
kasobol-msft Jan 11, 2021
4deba35
undo project references workaround.
kasobol-msft Jan 11, 2021
4b59f79
undo webjobs project ref workaround.
kasobol-msft Jan 11, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,24 @@ public async Task Batch_SasUri_NotOwner()
Assert.AreEqual(403, ex.Status);
}

[Test]
[LiveOnly]
public async Task Batch_AzureSasCredential()
{
// Create a container using SAS for Auth
await using DisposingContainer test = await GetTestContainerAsync();

var serviceClient = GetServiceClient_SharedKey();
var sas = GetAccountSasCredentials().SasToken;
var sasServiceClient = InstrumentClient(new BlobServiceClient(serviceClient.Uri, new AzureSasCredential(sas), GetOptions()));
await using TestScenario scenario = Scenario(sasServiceClient);
Uri[] blobs = await scenario.CreateBlobUrisAsync(test.Container, 2);
BlobBatchClient client = scenario.GetBlobBatchClient();
Response[] responses = await client.DeleteBlobsAsync(blobs);

scenario.AssertStatus(202, responses);
}

// TODO: Add a requirement that one of the test tenants is in a
// different account so we can verify batch requests fail across
// multiple storage accounts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public partial class BlobChangeFeedClient
protected BlobChangeFeedClient() { }
public BlobChangeFeedClient(string connectionString) { }
public BlobChangeFeedClient(string connectionString, Azure.Storage.Blobs.BlobClientOptions options) { }
public BlobChangeFeedClient(System.Uri serviceUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobChangeFeedClient(System.Uri serviceUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobChangeFeedClient(System.Uri serviceUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobChangeFeedClient(System.Uri serviceUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,31 @@ public BlobChangeFeedClient(Uri serviceUri, StorageSharedKeyCredential credentia
_blobServiceClient = new BlobServiceClient(serviceUri, credential, options);
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobChangeFeedClient"/>
/// class.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a blurb to all these doc comments telling people to only use this overload if they need to roll SAS signatures.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added remarks.

/// </summary>
/// <param name="serviceUri">
/// A <see cref="Uri"/> referencing the blob service.
/// This is likely to be similar to "https://{account_name}.blob.core.windows.net".
/// Must not contain shared access signature, which should be passed in the second parameter.
/// </param>
/// <param name="credential">
/// The shared access signature credential used to sign requests.
/// </param>
/// <param name="options">
/// Optional client options that define the transport pipeline
/// policies for authentication, retries, etc., that are applied to
/// every request.
/// </param>
/// <remarks>
/// This constructor should only be used when shared access signature needs to be updated during lifespan of this client.
/// </remarks>
public BlobChangeFeedClient(Uri serviceUri, AzureSasCredential credential, BlobClientOptions options = default)
{
_blobServiceClient = new BlobServiceClient(serviceUri, credential, options);
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobChangeFeedClient"/>
/// class.
Expand Down
1 change: 1 addition & 0 deletions sdk/storage/Azure.Storage.Blobs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 12.8.0-beta.2 (Unreleased)
- Fixed bug where the Stream returned by BlobBaseClient.OpenRead() would return a different Length after calls to Seek().
- Fixed bug where BlobBaseClient.Exists() did not function correctly for blob encrypted with Customer Provided Key or Encryption Scope.
- Added support for AzureSasCredential. That allows SAS rotation for long living clients.

## 12.8.0-beta.1 (2020-12-07)
- Added support for service version 2020-04-08.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public partial class BlobClient : Azure.Storage.Blobs.Specialized.BlobBaseClient
protected BlobClient() { }
public BlobClient(string connectionString, string blobContainerName, string blobName) { }
public BlobClient(string connectionString, string blobContainerName, string blobName, Azure.Storage.Blobs.BlobClientOptions options) { }
public BlobClient(System.Uri blobUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobClient(System.Uri blobUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobClient(System.Uri blobUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down Expand Up @@ -60,6 +61,7 @@ public partial class BlobContainerClient
protected BlobContainerClient() { }
public BlobContainerClient(string connectionString, string blobContainerName) { }
public BlobContainerClient(string connectionString, string blobContainerName, Azure.Storage.Blobs.BlobClientOptions options) { }
public BlobContainerClient(System.Uri blobContainerUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobContainerClient(System.Uri blobContainerUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobContainerClient(System.Uri blobContainerUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobContainerClient(System.Uri blobContainerUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down Expand Up @@ -119,6 +121,7 @@ public partial class BlobServiceClient
protected BlobServiceClient() { }
public BlobServiceClient(string connectionString) { }
public BlobServiceClient(string connectionString, Azure.Storage.Blobs.BlobClientOptions options) { }
public BlobServiceClient(System.Uri serviceUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobServiceClient(System.Uri serviceUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobServiceClient(System.Uri serviceUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobServiceClient(System.Uri serviceUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down Expand Up @@ -1224,6 +1227,7 @@ public partial class AppendBlobClient : Azure.Storage.Blobs.Specialized.BlobBase
protected AppendBlobClient() { }
public AppendBlobClient(string connectionString, string blobContainerName, string blobName) { }
public AppendBlobClient(string connectionString, string blobContainerName, string blobName, Azure.Storage.Blobs.BlobClientOptions options) { }
public AppendBlobClient(System.Uri blobUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public AppendBlobClient(System.Uri blobUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public AppendBlobClient(System.Uri blobUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public AppendBlobClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down Expand Up @@ -1257,6 +1261,7 @@ public partial class BlobBaseClient
protected BlobBaseClient() { }
public BlobBaseClient(string connectionString, string blobContainerName, string blobName) { }
public BlobBaseClient(string connectionString, string blobContainerName, string blobName, Azure.Storage.Blobs.BlobClientOptions options) { }
public BlobBaseClient(System.Uri blobUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobBaseClient(System.Uri blobUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobBaseClient(System.Uri blobUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlobBaseClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down Expand Up @@ -1361,6 +1366,7 @@ public partial class BlockBlobClient : Azure.Storage.Blobs.Specialized.BlobBaseC
protected BlockBlobClient() { }
public BlockBlobClient(string connectionString, string containerName, string blobName) { }
public BlockBlobClient(string connectionString, string blobContainerName, string blobName, Azure.Storage.Blobs.BlobClientOptions options) { }
public BlockBlobClient(System.Uri blobUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlockBlobClient(System.Uri blobUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlockBlobClient(System.Uri blobUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public BlockBlobClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down Expand Up @@ -1407,6 +1413,7 @@ public partial class PageBlobClient : Azure.Storage.Blobs.Specialized.BlobBaseCl
protected PageBlobClient() { }
public PageBlobClient(string connectionString, string blobContainerName, string blobName) { }
public PageBlobClient(string connectionString, string blobContainerName, string blobName, Azure.Storage.Blobs.BlobClientOptions options) { }
public PageBlobClient(System.Uri blobUri, Azure.AzureSasCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public PageBlobClient(System.Uri blobUri, Azure.Core.TokenCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public PageBlobClient(System.Uri blobUri, Azure.Storage.Blobs.BlobClientOptions options = null) { }
public PageBlobClient(System.Uri blobUri, Azure.Storage.StorageSharedKeyCredential credential, Azure.Storage.Blobs.BlobClientOptions options = null) { }
Expand Down
28 changes: 28 additions & 0 deletions sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,34 @@ public AppendBlobClient(Uri blobUri, StorageSharedKeyCredential credential, Blob
AssertNoClientSideEncryption(options);
}

/// <summary>
/// Initializes a new instance of the <see cref="AppendBlobClient"/>
/// class.
/// </summary>
/// <param name="blobUri">
/// A <see cref="Uri"/> referencing the append blob that includes the
/// name of the account, the name of the container, and the name of
/// the blob.
/// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}".
/// Must not contain shared access signature, which should be passed in the second parameter.
/// </param>
/// <param name="credential">
/// The shared access signature credential used to sign requests.
/// </param>
/// <param name="options">
/// Optional client options that define the transport pipeline
/// policies for authentication, retries, etc., that are applied to
/// every request.
/// </param>
/// <remarks>
/// This constructor should only be used when shared access signature needs to be updated during lifespan of this client.
/// </remarks>
public AppendBlobClient(Uri blobUri, AzureSasCredential credential, BlobClientOptions options = default)
: base(blobUri, credential, options)
{
AssertNoClientSideEncryption(options);
}

/// <summary>
/// Initializes a new instance of the <see cref="AppendBlobClient"/>
/// class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.Common\src\Azure.Storage.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(AzureCoreSharedSources)Argument.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)AzureResourceProviderNamespaceAttribute.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)AzureSasCredentialSynchronousPolicy.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)OperationHelpers.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)RetriableStream.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ArrayBufferWriter.cs" Link="Shared\Core\%(RecursiveDir)\%(Filename)%(Extension)" />
Expand Down
28 changes: 28 additions & 0 deletions sdk/storage/Azure.Storage.Blobs/src/BlobBaseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,33 @@ public BlobBaseClient(Uri blobUri, StorageSharedKeyCredential credential, BlobCl
{
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobBaseClient"/>
/// class.
/// </summary>
/// <param name="blobUri">
/// A <see cref="Uri"/> referencing the blob that includes the
/// name of the account, the name of the container, and the name of
/// the blob.
/// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}".
/// Must not contain shared access signature, which should be passed in the second parameter.
/// </param>
/// <param name="credential">
/// The shared access signature credential used to sign requests.
/// </param>
/// <param name="options">
/// Optional client options that define the transport pipeline
/// policies for authentication, retries, etc., that are applied to
/// every request.
/// </param>
/// <remarks>
/// This constructor should only be used when shared access signature needs to be updated during lifespan of this client.
/// </remarks>
public BlobBaseClient(Uri blobUri, AzureSasCredential credential, BlobClientOptions options = default)
: this(blobUri, credential.AsPolicy<BlobUriBuilder>(blobUri), options, null)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobBaseClient"/>
/// class.
Expand Down Expand Up @@ -352,6 +379,7 @@ internal BlobBaseClient(
BlobClientOptions options,
StorageSharedKeyCredential storageSharedKeyCredential)
{
Argument.AssertNotNull(blobUri, nameof(blobUri));
options ??= new BlobClientOptions();
_uri = blobUri;
if (!string.IsNullOrEmpty(blobUri.Query))
Expand Down
27 changes: 27 additions & 0 deletions sdk/storage/Azure.Storage.Blobs/src/BlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,33 @@ public BlobClient(Uri blobUri, StorageSharedKeyCredential credential, BlobClient
{
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobClient"/>
/// class.
/// </summary>
/// <param name="blobUri">
/// A <see cref="Uri"/> referencing the blob that includes the
/// name of the account, the name of the container, and the name of
/// the blob.
/// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}/{blob_name}".
/// Must not contain shared access signature, which should be passed in the second parameter.
/// </param>
/// <param name="credential">
/// The shared access signature credential used to sign requests.
/// </param>
/// <param name="options">
/// Optional client options that define the transport pipeline
/// policies for authentication, retries, etc., that are applied to
/// every request.
/// </param>
/// <remarks>
/// This constructor should only be used when shared access signature needs to be updated during lifespan of this client.
/// </remarks>
public BlobClient(Uri blobUri, AzureSasCredential credential, BlobClientOptions options = default)
: base(blobUri, credential, options)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobClient"/>
/// class.
Expand Down
27 changes: 27 additions & 0 deletions sdk/storage/Azure.Storage.Blobs/src/BlobContainerClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,32 @@ public BlobContainerClient(Uri blobContainerUri, StorageSharedKeyCredential cred
_storageSharedKeyCredential = credential;
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobContainerClient"/>
/// class.
/// </summary>
/// <param name="blobContainerUri">
/// A <see cref="Uri"/> referencing the blob container that includes the
/// name of the account and the name of the container.
/// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}".
/// Must not contain shared access signature, which should be passed in the second parameter.
/// </param>
/// <param name="credential">
/// The shared access signature credential used to sign requests.
/// </param>
/// <param name="options">
/// Optional client options that define the transport pipeline
/// policies for authentication, retries, etc., that are applied to
/// every request.
/// </param>
/// <remarks>
/// This constructor should only be used when shared access signature needs to be updated during lifespan of this client.
/// </remarks>
public BlobContainerClient(Uri blobContainerUri, AzureSasCredential credential, BlobClientOptions options = default)
: this(blobContainerUri, credential.AsPolicy<BlobUriBuilder>(blobContainerUri), options)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="BlobContainerClient"/>
/// class.
Expand Down Expand Up @@ -317,6 +343,7 @@ public BlobContainerClient(Uri blobContainerUri, TokenCredential credential, Blo
/// </param>
internal BlobContainerClient(Uri blobContainerUri, HttpPipelinePolicy authentication, BlobClientOptions options)
{
Argument.AssertNotNull(blobContainerUri, nameof(blobContainerUri));
_uri = blobContainerUri;
options ??= new BlobClientOptions();
_pipeline = options.Build(authentication);
Expand Down
Loading