Skip to content

Commit

Permalink
feat: improve support for mutable credentials (#461)
Browse files Browse the repository at this point in the history
Improve support for credentials inheriting from Amazon.Runtime.AWSCredentials.

Closes #458
  • Loading branch information
FantasticFiasco authored Jul 30, 2021
1 parent 6997ec6 commit 5bd6ed1
Show file tree
Hide file tree
Showing 10 changed files with 1,701 additions and 20 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](http://semver.org/) and is followi

## Unreleased

### :zap: Added

- [#458](https://github.com/FantasticFiasco/aws-signature-version-4/issues/458) Improve support for AWS credentials inheriting from `Amazon.Runtime.AWSCredentials`

## [1.4.1] - 2021-06-09

### :syringe: Fixed
Expand Down
6 changes: 4 additions & 2 deletions src/AwsSignatureHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@ protected override async Task<HttpResponseMessage> SendAsync(
request.Headers.Remove(HeaderKeys.XAmzContentSha256Header);
request.Headers.Remove(HeaderKeys.XAmzDateHeader);
request.Headers.Remove(HeaderKeys.XAmzSecurityTokenHeader);


var immutableCredentials = await settings.Credentials.GetCredentialsAsync();

await Signer.SignAsync(
request,
null,
EmptyRequestHeaders,
DateTime.UtcNow,
settings.RegionName,
settings.ServiceName,
settings.Credentials);
immutableCredentials);

return await base.SendAsync(request, cancellationToken);
}
Expand Down
26 changes: 25 additions & 1 deletion src/AwsSignatureHandlerSettings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Amazon.Runtime;
using AwsSignatureVersion4.Private;

namespace AwsSignatureVersion4
{
Expand All @@ -25,6 +26,29 @@ public class AwsSignatureHandlerSettings
/// security credentials, e.g. a role.
/// </param>
public AwsSignatureHandlerSettings(string regionName, string serviceName, ImmutableCredentials credentials)
{
RegionName = regionName ?? throw new ArgumentNullException(nameof(regionName));
ServiceName = serviceName ?? throw new ArgumentNullException(nameof(serviceName));
Credentials = new AWSCredentialsWrapper(credentials ?? throw new ArgumentNullException(nameof(credentials)));
}

/// <summary>
/// Initializes a new instance of the <see cref="AwsSignatureHandlerSettings"/> class.
/// </summary>
/// <param name="regionName">
/// The system name of the AWS region associated with the endpoint, e.g. "us-east-1".
/// </param>
/// <param name="serviceName">
/// The signing name of the service, e.g. "execute-api".
/// </param>
/// <param name="credentials">
/// AWS credentials containing the following parameters:
/// - The AWS public key for the account making the service call.
/// - The AWS secret key for the account making the call, in clear text.
/// - The session token obtained from STS if request is authenticated using temporary
/// security credentials, e.g. a role.
/// </param>
public AwsSignatureHandlerSettings(string regionName, string serviceName, AWSCredentials credentials)
{
RegionName = regionName ?? throw new ArgumentNullException(nameof(regionName));
ServiceName = serviceName ?? throw new ArgumentNullException(nameof(serviceName));
Expand All @@ -48,6 +72,6 @@ public AwsSignatureHandlerSettings(string regionName, string serviceName, Immuta
/// - The session token obtained from STS if request is authenticated using temporary
/// security credentials, e.g. a role.
/// </summary>
public ImmutableCredentials Credentials { get; }
public AWSCredentials Credentials { get; }
}
}
256 changes: 256 additions & 0 deletions src/DeleteAsyncExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,65 @@ namespace System.Net.Http
/// </summary>
public static class DeleteAsyncExtensions
{
#region DeleteAsync(string, string, string, <credentials>)

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri as an
/// asynchronous operation.
/// </summary>
/// <param name="self">
/// The extension target.
/// </param>
/// <param name="requestUri">
/// The Uri the request is sent to.
/// </param>
/// <param name="regionName">
/// The system name of the AWS region associated with the endpoint, e.g. "us-east-1".
/// </param>
/// <param name="serviceName">
/// The signing name of the service, e.g. "execute-api".
/// </param>
/// <param name="credentials">
/// AWS credentials containing the following parameters:
/// - The AWS public key for the account making the service call.
/// - The AWS secret key for the account making the call, in clear text.
/// - The session token obtained from STS if request is authenticated using temporary
/// security credentials, e.g. a role.
/// </param>
/// <returns>
/// The task object representing the asynchronous operation.
/// </returns>
/// <exception cref="ArgumentNullException">
/// The <paramref name="requestUri"/> is null.
/// </exception>
/// <exception cref="HttpRequestException">
/// The request failed due to an underlying issue such as network connectivity, DNS
/// failure, server certificate validation or timeout.
/// </exception>
/// <remarks>
/// This operation will not block. The returned <see cref="Task{TResult}"/> object will
/// complete once the entire response including content is read.
/// </remarks>
public static async Task<HttpResponseMessage> DeleteAsync(
this HttpClient self,
string requestUri,
string regionName,
string serviceName,
AWSCredentials credentials)
{
if (credentials == null) throw new ArgumentNullException(nameof(credentials));

var immutableCredentials = await credentials.GetCredentialsAsync();

var response = await self.DeleteAsync(
requestUri,
regionName,
serviceName,
immutableCredentials);

return response;
}

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri as an
/// asynchronous operation.
Expand Down Expand Up @@ -61,6 +120,67 @@ public static Task<HttpResponseMessage> DeleteAsync(
serviceName,
credentials);

#endregion

#region DeleteAsync(Uri, string, string, <credentials>)

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri as an
/// asynchronous operation.
/// </summary>
/// <param name="self">
/// The extension target.
/// </param>
/// <param name="requestUri">
/// The Uri the request is sent to.
/// </param>
/// <param name="regionName">
/// The system name of the AWS region associated with the endpoint, e.g. "us-east-1".
/// </param>
/// <param name="serviceName">
/// The signing name of the service, e.g. "execute-api".
/// </param>
/// <param name="credentials">
/// AWS credentials containing the following parameters:
/// - The AWS public key for the account making the service call.
/// - The AWS secret key for the account making the call, in clear text.
/// - The session token obtained from STS if request is authenticated using temporary
/// security credentials, e.g. a role.
/// </param>
/// <returns>
/// The task object representing the asynchronous operation.
/// </returns>
/// <exception cref="ArgumentNullException">
/// The <paramref name="requestUri"/> is null.
/// </exception>
/// <exception cref="HttpRequestException">
/// The request failed due to an underlying issue such as network connectivity, DNS
/// failure, server certificate validation or timeout.
/// </exception>
/// <remarks>
/// This operation will not block. The returned <see cref="Task{TResult}"/> object will
/// complete once the entire response including content is read.
/// </remarks>
public static async Task<HttpResponseMessage> DeleteAsync(
this HttpClient self,
Uri requestUri,
string regionName,
string serviceName,
AWSCredentials credentials)
{
if (credentials == null) throw new ArgumentNullException(nameof(credentials));

var immutableCredentials = await credentials.GetCredentialsAsync();

var response = await self.DeleteAsync(
requestUri,
regionName,
serviceName,
immutableCredentials);

return response;
}

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri as an
/// asynchronous operation.
Expand Down Expand Up @@ -111,6 +231,73 @@ public static Task<HttpResponseMessage> DeleteAsync(
serviceName,
credentials);

#endregion

#region DeleteAsync(string, CancellationToken, string, string, <credentials>)

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri with a
/// cancellation token as an asynchronous operation.
/// </summary>
/// <param name="self">
/// The extension target.
/// </param>
/// <param name="requestUri">
/// The Uri the request is sent to.
/// </param>
/// <param name="cancellationToken">
/// A cancellation token that can be used by other objects or threads to receive notice of
/// cancellation.
/// </param>
/// <param name="regionName">
/// The system name of the AWS region associated with the endpoint, e.g. "us-east-1".
/// </param>
/// <param name="serviceName">
/// The signing name of the service, e.g. "execute-api".
/// </param>
/// <param name="credentials">
/// AWS credentials containing the following parameters:
/// - The AWS public key for the account making the service call.
/// - The AWS secret key for the account making the call, in clear text.
/// - The session token obtained from STS if request is authenticated using temporary
/// security credentials, e.g. a role.
/// </param>
/// <returns>
/// The task object representing the asynchronous operation.
/// </returns>
/// <exception cref="ArgumentNullException">
/// The <paramref name="requestUri"/> is null.
/// </exception>
/// <exception cref="HttpRequestException">
/// The request failed due to an underlying issue such as network connectivity, DNS
/// failure, server certificate validation or timeout.
/// </exception>
/// <remarks>
/// This operation will not block. The returned <see cref="Task{TResult}"/> object will
/// complete once the entire response including content is read.
/// </remarks>
public static async Task<HttpResponseMessage> DeleteAsync(
this HttpClient self,
string requestUri,
CancellationToken cancellationToken,
string regionName,
string serviceName,
AWSCredentials credentials)
{
if (credentials == null) throw new ArgumentNullException(nameof(credentials));

var immutableCredentials = await credentials.GetCredentialsAsync();

var response = await self.DeleteAsync(
requestUri,
cancellationToken,
regionName,
serviceName,
immutableCredentials);

return response;
}

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri with a
/// cancellation token as an asynchronous operation.
Expand Down Expand Up @@ -166,6 +353,73 @@ public static Task<HttpResponseMessage> DeleteAsync(
serviceName,
credentials);

#endregion

#region DeleteAsync(Uri, CancellationToken, string, string, <credentials>)

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri with a
/// cancellation token as an asynchronous operation.
/// </summary>
/// <param name="self">
/// The extension target.
/// </param>
/// <param name="requestUri">
/// The Uri the request is sent to.
/// </param>
/// <param name="cancellationToken">
/// A cancellation token that can be used by other objects or threads to receive notice of
/// cancellation.
/// </param>
/// <param name="regionName">
/// The system name of the AWS region associated with the endpoint, e.g. "us-east-1".
/// </param>
/// <param name="serviceName">
/// The signing name of the service, e.g. "execute-api".
/// </param>
/// <param name="credentials">
/// AWS credentials containing the following parameters:
/// - The AWS public key for the account making the service call.
/// - The AWS secret key for the account making the call, in clear text.
/// - The session token obtained from STS if request is authenticated using temporary
/// security credentials, e.g. a role.
/// </param>
/// <returns>
/// The task object representing the asynchronous operation.
/// </returns>
/// <exception cref="ArgumentNullException">
/// The <paramref name="requestUri"/> is null.
/// </exception>
/// <exception cref="HttpRequestException">
/// The request failed due to an underlying issue such as network connectivity, DNS
/// failure, server certificate validation or timeout.
/// </exception>
/// <remarks>
/// This operation will not block. The returned <see cref="Task{TResult}"/> object will
/// complete once the entire response including content is read.
/// </remarks>
public static async Task<HttpResponseMessage> DeleteAsync(
this HttpClient self,
Uri requestUri,
CancellationToken cancellationToken,
string regionName,
string serviceName,
AWSCredentials credentials)
{
if (credentials == null) throw new ArgumentNullException(nameof(credentials));

var immutableCredentials = await credentials.GetCredentialsAsync();

var response = await self.DeleteAsync(
requestUri,
cancellationToken,
regionName,
serviceName,
immutableCredentials);

return response;
}

/// <summary>
/// Send a Signature Version 4 signed DELETE request to the specified Uri with a
/// cancellation token as an asynchronous operation.
Expand Down Expand Up @@ -220,5 +474,7 @@ public static Task<HttpResponseMessage> DeleteAsync(
regionName,
serviceName,
credentials);

#endregion
}
}
Loading

0 comments on commit 5bd6ed1

Please sign in to comment.