/// <summary> /// Use an account's <see cref="TableSharedKeyCredential"/> to sign this /// shared access signature values to produce the proper SAS query /// parameters for authenticating requests. /// </summary> /// <param name="sharedKeyCredential"> /// The storage account's <see cref="TableSharedKeyCredential"/>. /// </param> /// <returns> /// An instance of <see cref="TableSasQueryParameters"/>. /// </returns> public TableSasQueryParameters ToSasQueryParameters(TableSharedKeyCredential sharedKeyCredential) { sharedKeyCredential = sharedKeyCredential ?? throw Errors.ArgumentNull(nameof(sharedKeyCredential)); EnsureState(); var startTime = TableSasExtensions.FormatTimesForSasSigning(StartsOn); var expiryTime = TableSasExtensions.FormatTimesForSasSigning(ExpiresOn); // String to sign: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx var stringToSign = string.Join("\n", Permissions, startTime, expiryTime, GetCanonicalName(sharedKeyCredential.AccountName, TableName), Identifier, IPRange.ToString(), TableSasExtensions.ToProtocolString(Protocol), Version, PartitionKeyStart, RowKeyStart, PartitionKeyEnd, RowKeyEnd); var signature = TableSharedKeyCredential.ComputeSasSignature(sharedKeyCredential, stringToSign); var p = new TableSasQueryParameters( version: Version, resourceTypes: default,
//TODO: implement Singleton pattern for TableClient private TableClient GetTableClient() { var credentials = new TableSharedKeyCredential(_settings.Value.AccountName, _settings.Value.AccountKey); var tableClient = new TableClient(new Uri(_settings.Value.TableUrl), _settings.Value.TableName, credentials); return(tableClient); }
public async Task SasAuth() { string storageUri = StorageUri; string accountName = StorageAccountName; string accountKey = PrimaryStorageAccountKey; string tableName = "OfficeSupplies"; #region Snippet:TablesAuthSas // Construct a new <see cref="TableServiceClient" /> using a <see cref="TableSharedKeyCredential" />. var credential = new TableSharedKeyCredential(accountName, accountKey); var serviceClient = new TableServiceClient( new Uri(storageUri), credential); // Build a shared access signature with the Write and Delete permissions and access to all service resource types. TableAccountSasBuilder sasWriteDelete = serviceClient.GetSasBuilder(TableAccountSasPermissions.Write | TableAccountSasPermissions.Delete, TableAccountSasResourceTypes.All, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string tokenWriteDelete = sasWriteDelete.Sign(credential); // Create the TableServiceClients using the SAS URIs. var serviceClientWithSas = new TableServiceClient(new Uri(storageUri), new AzureSasCredential(tokenWriteDelete)); // Validate that we are able to create a table using the SAS URI with Write and Delete permissions. await serviceClientWithSas.CreateTableIfNotExistsAsync(tableName); // Validate that we are able to delete a table using the SAS URI with Write and Delete permissions. await serviceClientWithSas.DeleteTableAsync(tableName); #endregion }
public void ValidateSasCredentials() { // Create a SharedKeyCredential that we can use to sign the SAS token var credential = new TableSharedKeyCredential(TestEnvironment.AccountName, TestEnvironment.PrimaryStorageAccountKey); // Build a shared access signature with only Read permissions. TableSasBuilder sas = client.GetSasBuilder(TableSasPermissions.Read, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string token = sas.Sign(credential); // Build a SAS URI UriBuilder sasUri = new UriBuilder(TestEnvironment.StorageUri) { Query = token }; // Create the TableServiceClient using the SAS URI. var sasAuthedService = InstrumentClient(new TableServiceClient(sasUri.Uri, Recording.InstrumentClientOptions(new TableClientOptions()))); var sasTableclient = sasAuthedService.GetTableClient(tableName); // Validate that we are able to query the table from the service. Assert.That(async() => await sasTableclient.QueryAsync().ToEnumerableAsync().ConfigureAwait(false), Throws.Nothing); // Validate that we are not able to upsert an entity to the table. Assert.That(async() => await sasTableclient.UpsertEntityAsync(CreateTableEntities("partition", 1).First(), UpdateMode.Replace).ConfigureAwait(false), Throws.InstanceOf <RequestFailedException>().And.Property("Status").EqualTo((int)HttpStatusCode.Forbidden)); }
public void ValidateAccountSasCredentialsWithResourceTypes() { // Create a SharedKeyCredential that we can use to sign the SAS token var credential = new TableSharedKeyCredential(TestEnvironment.StorageAccountName, TestEnvironment.PrimaryStorageAccountKey); // Build a shared access signature with all permissions and access to only Service resource types. TableAccountSasBuilder sasService = service.GetSasBuilder(TableAccountSasPermissions.All, TableAccountSasResourceTypes.Service, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string tokenService = sasService.Sign(credential); // Build a shared access signature with all permissions and access to Service and Container resource types. TableAccountSasBuilder sasServiceContainer = service.GetSasBuilder(TableAccountSasPermissions.All, TableAccountSasResourceTypes.Service | TableAccountSasResourceTypes.Container, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string tokenServiceContainer = sasServiceContainer.Sign(credential); // Build SAS URIs. UriBuilder sasUriService = new UriBuilder(ServiceUri) { Query = tokenService }; UriBuilder sasUriServiceContainer = new UriBuilder(ServiceUri) { Query = tokenServiceContainer }; // Create the TableServiceClients using the SAS URIs. var sasAuthedServiceClientService = InstrumentClient(new TableServiceClient(new Uri(ServiceUri), new AzureSasCredential(tokenService), InstrumentClientOptions(new TableClientOptions()))); var sasAuthedServiceClientServiceContainer = InstrumentClient(new TableServiceClient(new Uri(ServiceUri), new AzureSasCredential(tokenServiceContainer), InstrumentClientOptions(new TableClientOptions()))); // Validate that we are unable to create a table using the SAS URI with access to Service resource types. var sasTableName = Recording.GenerateAlphaNumericId("testtable", useOnlyLowercase: true); var ex = Assert.ThrowsAsync <RequestFailedException>(async() => await sasAuthedServiceClientService.CreateTableAsync(sasTableName).ConfigureAwait(false)); Assert.That(ex.Status, Is.EqualTo((int)HttpStatusCode.Forbidden)); Assert.That(ex.ErrorCode, Is.EqualTo(TableErrorCode.AuthorizationResourceTypeMismatch.ToString())); // Validate that we are able to create a table using the SAS URI with access to Service and Container resource types. Assert.That(async() => await sasAuthedServiceClientServiceContainer.CreateTableAsync(sasTableName).ConfigureAwait(false), Throws.Nothing); // Validate that we are able to get table service properties using the SAS URI with access to Service resource types. Assert.That(async() => await sasAuthedServiceClientService.GetPropertiesAsync().ConfigureAwait(false), Throws.Nothing); // Validate that we are able to get table service properties using the SAS URI with access to Service and Container resource types. Assert.That(async() => await sasAuthedServiceClientService.GetPropertiesAsync().ConfigureAwait(false), Throws.Nothing); // Validate that we are able to delete a table using the SAS URI with access to Service and Container resource types. Assert.That(async() => await sasAuthedServiceClientServiceContainer.DeleteTableAsync(sasTableName).ConfigureAwait(false), Throws.Nothing); }
private static IEnumerable <object[]> TableServiceClients() { var cred = new TableSharedKeyCredential(AccountName, Secret); var sharedKeyClient = new TableServiceClient(_url, cred); var connStringClient = new TableServiceClient($"DefaultEndpointsProtocol=https;AccountName={AccountName};AccountKey={Secret};TableEndpoint=https://{AccountName}.table.cosmos.azure.com:443/;"); yield return(new object[] { sharedKeyClient, cred }); yield return(new object[] { connStringClient, cred }); }
public void GenerateSasUri(TableServiceClient client, TableSharedKeyCredential cred) { TableAccountSasPermissions permissions = TableAccountSasPermissions.Add; TableAccountSasResourceTypes resourceTypes = TableAccountSasResourceTypes.Container; var expires = DateTime.Now.AddDays(1); var expectedSas = new TableAccountSasBuilder(permissions, resourceTypes, expires).Sign(cred); var actualSas = client.GenerateSasUri(permissions, resourceTypes, expires); Assert.AreEqual("?" + expectedSas, actualSas.Query); }
/// <summary> /// Configures the <see cref="TableServiceClient"/> using an authenticated service URI and a <see cref="TableSharedKeyCredential"/>. /// </summary> public void ConfigureTableServiceClient(Uri serviceUri, TableSharedKeyCredential sharedKeyCredential) { if (serviceUri is null) { throw new ArgumentNullException(nameof(serviceUri)); } if (sharedKeyCredential is null) { throw new ArgumentNullException(nameof(sharedKeyCredential)); } CreateClient = () => Task.FromResult(new TableServiceClient(serviceUri, sharedKeyCredential, ClientOptions)); }
public void ValidateAccountSasCredentialsWithPermissionsWithSasDuplicatedInUri() { // Create a SharedKeyCredential that we can use to sign the SAS token var credential = new TableSharedKeyCredential(TestEnvironment.StorageAccountName, TestEnvironment.PrimaryStorageAccountKey); // Build a shared access signature with only Delete permissions and access to all service resource types. TableAccountSasBuilder sasDelete = service.GetSasBuilder(TableAccountSasPermissions.Delete, TableAccountSasResourceTypes.All, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string tokenDelete = sasDelete.Sign(credential); // Build a shared access signature with the Write and Delete permissions and access to all service resource types. TableAccountSasBuilder sasWriteDelete = service.GetSasBuilder(TableAccountSasPermissions.Write, TableAccountSasResourceTypes.All, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string tokenWriteDelete = sasWriteDelete.Sign(credential); // Build SAS URIs. UriBuilder sasUriDelete = new UriBuilder(ServiceUri) { Query = tokenDelete }; UriBuilder sasUriWriteDelete = new UriBuilder(ServiceUri) { Query = tokenWriteDelete }; // Create the TableServiceClients using the SAS URIs. // Intentionally double add the Sas to the endpoint and the cred to validate de-duping var sasAuthedServiceDelete = InstrumentClient(new TableServiceClient(sasUriDelete.Uri, new AzureSasCredential(tokenDelete), InstrumentClientOptions(new TableClientOptions()))); var sasAuthedServiceWriteDelete = InstrumentClient(new TableServiceClient(sasUriWriteDelete.Uri, new AzureSasCredential(tokenWriteDelete), InstrumentClientOptions(new TableClientOptions()))); // Validate that we are unable to create a table using the SAS URI with only Delete permissions. var sasTableName = Recording.GenerateAlphaNumericId("testtable", useOnlyLowercase: true); var ex = Assert.ThrowsAsync <RequestFailedException>(async() => await sasAuthedServiceDelete.CreateTableAsync(sasTableName).ConfigureAwait(false)); Assert.That(ex.Status, Is.EqualTo((int)HttpStatusCode.Forbidden)); Assert.That(ex.ErrorCode, Is.EqualTo(TableErrorCode.AuthorizationPermissionMismatch.ToString())); // Validate that we are able to create a table using the SAS URI with Write and Delete permissions. Assert.That(async() => await sasAuthedServiceWriteDelete.CreateTableAsync(sasTableName).ConfigureAwait(false), Throws.Nothing); // Validate that we are able to delete a table using the SAS URI with only Delete permissions. Assert.That(async() => await sasAuthedServiceDelete.DeleteTableAsync(sasTableName).ConfigureAwait(false), Throws.Nothing); }
public void ValidateAccountSasCredentialsWithPermissions() { // Create a SharedKeyCredential that we can use to sign the SAS token var credential = new TableSharedKeyCredential(TestEnvironment.StorageAccountName, TestEnvironment.PrimaryStorageAccountKey); // Build a shared access signature with only Delete permissions and access to all service resource types. TableAccountSasBuilder sasDelete = service.GetSasBuilder(TableAccountSasPermissions.Delete, TableAccountSasResourceTypes.All, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string tokenDelete = sasDelete.Sign(credential); // Build a shared access signature with the Write and Delete permissions and access to all service resource types. TableAccountSasBuilder sasWriteDelete = service.GetSasBuilder(TableAccountSasPermissions.Write, TableAccountSasResourceTypes.All, new DateTime(2040, 1, 1, 1, 1, 0, DateTimeKind.Utc)); string tokenWriteDelete = sasWriteDelete.Sign(credential); // Build SAS URIs. UriBuilder sasUriDelete = new UriBuilder(TestEnvironment.StorageUri) { Query = tokenDelete }; UriBuilder sasUriWriteDelete = new UriBuilder(TestEnvironment.StorageUri) { Query = tokenWriteDelete }; // Create the TableServiceClients using the SAS URIs. var sasAuthedServiceDelete = InstrumentClient(new TableServiceClient(sasUriDelete.Uri, Recording.InstrumentClientOptions(new TableClientOptions()))); var sasAuthedServiceWriteDelete = InstrumentClient(new TableServiceClient(sasUriWriteDelete.Uri, Recording.InstrumentClientOptions(new TableClientOptions()))); // Validate that we are unable to create a table using the SAS URI with only Delete permissions. var sasTableName = Recording.GenerateAlphaNumericId("testtable", useOnlyLowercase: true); Assert.That(async() => await sasAuthedServiceDelete.CreateTableAsync(sasTableName).ConfigureAwait(false), Throws.InstanceOf <RequestFailedException>().And.Property("Status").EqualTo((int)HttpStatusCode.Forbidden)); // Validate that we are able to create a table using the SAS URI with Write and Delete permissions. Assert.That(async() => await sasAuthedServiceWriteDelete.CreateTableAsync(sasTableName).ConfigureAwait(false), Throws.Nothing); // Validate that we are able to delete a table using the SAS URI with only Delete permissions. Assert.That(async() => await sasAuthedServiceDelete.DeleteTableAsync(sasTableName).ConfigureAwait(false), Throws.Nothing); }
/// <summary> /// Add a health check for Azure CosmosDb/ Azure Storage table. /// </summary> /// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param> /// <param name="endpoint">The CosmosDB Table or Azure Storage Table uri endopoint.</param> /// <param name="credentials">The table shared key credentials to be used.</param> /// <param name="tableName">Table name to check for existence.</param> /// <param name="name">The health check name. Optional. If <c>null</c> the type name 'cosmosdb' will be used for the name.</param> /// <param name="failureStatus"> /// The <see cref="HealthStatus"/> that should be reported when the health check fails. Optional. If <c>null</c> then /// the default status of <see cref="HealthStatus.Unhealthy"/> will be reported. /// </param> /// <param name="tags">A list of tags that can be used to filter sets of health checks. Optional.</param> /// <param name="timeout">An optional <see cref="TimeSpan"/> representing the timeout of the check.</param> /// <returns>The specified <paramref name="builder"/>.</returns> public static IHealthChecksBuilder AddAzureTable( this IHealthChecksBuilder builder, Uri endpoint, TableSharedKeyCredential credentials, string tableName, string?name = default, HealthStatus?failureStatus = default, IEnumerable <string>?tags = default, TimeSpan?timeout = default) { return(builder.Add(new HealthCheckRegistration( name ?? TABLE_NAME, sp => new TableServiceHealthCheck(endpoint, credentials, tableName), failureStatus, tags, timeout))); }
private static TableClient ConstructTableClientFromCloudTable(CloudTable cloudTable, TableClientOptions options) { TableClient tableClient; if (cloudTable.ServiceClient.Credentials.IsSAS) { AzureSasCredential sasCredential = new AzureSasCredential(cloudTable.ServiceClient.Credentials.SASToken); tableClient = new TableClient(cloudTable.Uri, sasCredential, options); } else if (cloudTable.ServiceClient.Credentials.IsSharedKey) { TableSharedKeyCredential keyCredential = new TableSharedKeyCredential( cloudTable.ServiceClient.Credentials.AccountName, cloudTable.ServiceClient.Credentials.Key); tableClient = new TableClient(cloudTable.Uri, cloudTable.Name, keyCredential, options); } else // IsAnonymous { tableClient = new TableClient(cloudTable.Uri, options); } return(tableClient); }
/// <summary> /// Use an account's <see cref="TableSharedKeyCredential"/> to sign this /// shared access signature values to produce the proper SAS query /// parameters for authenticating requests. /// </summary> /// <param name="sharedKeyCredential"> /// The storage account's <see cref="TableSharedKeyCredential"/>. /// </param> /// <returns> /// An instance of <see cref="TableAccountSasQueryParameters"/>. /// </returns> public TableAccountSasQueryParameters ToSasQueryParameters(TableSharedKeyCredential sharedKeyCredential) { sharedKeyCredential = sharedKeyCredential ?? throw Errors.ArgumentNull(nameof(sharedKeyCredential)); EnsureState(); var startTime = TableSasExtensions.FormatTimesForSasSigning(StartsOn); var expiryTime = TableSasExtensions.FormatTimesForSasSigning(ExpiresOn); // String to sign: https://docs.microsoft.com/en-us/rest/api/storageservices/create-account-sas#constructing-the-signature-string var stringToSign = string.Join("\n", sharedKeyCredential.AccountName, Permissions, TableConstants.Sas.TableAccountServices.Table, ResourceTypes.ToPermissionsString(), startTime, expiryTime, IPRange.ToString(), Protocol.ToProtocolString(), Version, ""); var signature = TableSharedKeyCredential.ComputeSasSignature(sharedKeyCredential, stringToSign); var p = new TableAccountSasQueryParameters( version: Version, resourceTypes: ResourceTypes, protocol: Protocol, startsOn: StartsOn, expiresOn: ExpiresOn, ipRange: IPRange, identifier: Identifier, resource: null, permissions: Permissions, signature: signature); return(p); }
public TableServiceHealthCheck(Uri endpoint, TableSharedKeyCredential credentials, string tableName) { _endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); _credentials = credentials ?? throw new ArgumentNullException(nameof(credentials)); _tableName = tableName ?? throw new ArgumentNullException(nameof(tableName)); }
/// <summary> /// Use an account's <see cref="TableSharedKeyCredential"/> to sign this /// shared access signature values to produce the proper SAS query /// parameters for authenticating requests. /// </summary> /// <param name="sharedKeyCredential"> /// The storage account's <see cref="TableSharedKeyCredential"/>. /// </param> /// <returns> /// A URL encoded query string representing the SAS. /// </returns> public string Sign(TableSharedKeyCredential sharedKeyCredential) => ToSasQueryParameters(sharedKeyCredential).ToString();
private string GetExpectedHash(TableSharedKeyCredential cred) => cred.ComputeHMACSHA256("message");
/// <summary> /// Registers a <see cref="TableServiceClient"/> instance with the provided <paramref name="serviceUri"/> and <paramref name="sharedKeyCredential"/> /// </summary> public static IAzureClientBuilder <TableServiceClient, TablesClientOptions> AddTableServiceClient <TBuilder>(this TBuilder builder, Uri serviceUri, TableSharedKeyCredential sharedKeyCredential) where TBuilder : IAzureClientFactoryBuilder { return(builder.RegisterClientFactory <TableServiceClient, TablesClientOptions>(options => new TableServiceClient(serviceUri, sharedKeyCredential, options))); }