Skip to content

Commit 75a8b12

Browse files
committed
Added a signer class for System.Net.Http.HttpClient
1 parent b5b91f9 commit 75a8b12

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.Net.Http;
3+
using System.Net.Http.Headers;
4+
using System.Security.Cryptography;
5+
using System.Text;
6+
7+
namespace Mastercard.Developer.OAuth1Signer.Core.Signers
8+
{
9+
/// <summary>
10+
/// Utility class for signing System.Net.Http.HttpClient request objects.
11+
/// </summary>
12+
public class NetHttpClientSigner : BaseSigner
13+
{
14+
public NetHttpClientSigner(string consumerKey, RSA signingKey) : base(consumerKey, signingKey)
15+
{
16+
}
17+
18+
public NetHttpClientSigner(string consumerKey, RSA signingKey, Encoding encoding) : base(consumerKey, signingKey, encoding)
19+
{
20+
}
21+
22+
public void Sign(HttpRequestMessage request)
23+
{
24+
if (request == null) throw new ArgumentNullException(nameof(request));
25+
26+
string payload = null;
27+
var httpContent = request.Content;
28+
if (httpContent != null)
29+
{
30+
// Read the body
31+
var bodyTask = httpContent.ReadAsStringAsync();
32+
bodyTask.Wait();
33+
payload = bodyTask.Result;
34+
}
35+
36+
// Generate the header and add it to the request
37+
var methodString = request.Method.ToString();
38+
var header = OAuth.GetAuthorizationHeader(request.RequestUri.AbsoluteUri, methodString, payload, Encoding, ConsumerKey, SigningKey);
39+
request.Headers.Authorization = new AuthenticationHeaderValue("OAuth", header.Replace("OAuth", string.Empty));
40+
}
41+
}
42+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Net.Http;
3+
using Mastercard.Developer.OAuth1Signer.Core.Signers;
4+
using Mastercard.Developer.OAuth1Signer.Tests.Test;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
7+
namespace Mastercard.Developer.OAuth1Signer.Tests.Signers
8+
{
9+
[TestClass]
10+
public class NetHttpClientSignerTest
11+
{
12+
[TestMethod]
13+
public void TestSign_ShouldAddOAuth1HeaderToRequest()
14+
{
15+
// GIVEN
16+
var signingKey = TestUtils.GetTestPrivateKey();
17+
const string consumerKey = "Some key";
18+
var request = new HttpRequestMessage
19+
{
20+
Method = HttpMethod.Post,
21+
RequestUri = new Uri("https://api.mastercard.com/service"),
22+
Content = new StringContent("{\"foo\":\"bår\"}") // "application/json; charset=utf-8"
23+
};
24+
25+
// WHEN
26+
var instanceUnderTest = new NetHttpClientSigner(consumerKey, signingKey);
27+
instanceUnderTest.Sign(request);
28+
29+
// THEN
30+
Assert.IsNotNull(request.Headers.Authorization);
31+
}
32+
}
33+
}

README.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,41 @@ These classes will modify the provided request object in-place and will add the
8383

8484
Usage briefly described below, but you can also refer to the test project for examples.
8585

86+
+ [System.Net.Http.HttpClient](#system-net-http-httpclient)
8687
+ [RestSharp Portable](#restsharp-portable)
8788

89+
#### System.Net.Http.HttpClient <a name="system-net-http-httpclient"></a>
90+
91+
The `NetHttpClientSigner` class is located in the `Mastercard.Developer.OAuth1Signer.Core` package.
92+
93+
Usage:
94+
```cs
95+
var baseUri = new Uri("https://api.mastercard.com/");
96+
var httpClient = new HttpClient(new RequestSignerHandler(ConsumerKey, signingKey)) { BaseAddress = baseUri };
97+
var postTask = httpClient.PostAsync(new Uri("/service", UriKind.Relative), new StringContent("{\"foo\":\"bår\"}");
98+
99+
// (...)
100+
101+
internal class RequestSignerHandler : HttpClientHandler
102+
{
103+
private readonly NetHttpClientSigner signer;
104+
105+
public RequestSignerHandler(string consumerKey, RSA signingKey)
106+
{
107+
signer = new NetHttpClientSigner(consumerKey, signingKey);
108+
}
109+
110+
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
111+
{
112+
signer.Sign(request);
113+
return base.SendAsync(request, cancellationToken);
114+
}
115+
}
116+
```
117+
88118
#### RestSharp Portable <a name="restsharp-portable"></a>
89119

90-
The `RestSharpSigner` class is provided by the `Mastercard.Developer.OAuth1Signer.RestSharp` package.
120+
The `RestSharpSigner` class is located in the `Mastercard.Developer.OAuth1Signer.RestSharp` package.
91121

92122
Usage:
93123
```cs
@@ -128,7 +158,7 @@ config.json:
128158

129159
##### Usage of the RestSharpOAuth1Authenticator
130160

131-
`RestSharpOAuth1Authenticator` is provided in the `Mastercard.Developer.OAuth1Signer.RestSharp` package.
161+
`RestSharpOAuth1Authenticator` is located in the `Mastercard.Developer.OAuth1Signer.RestSharp` package.
132162

133163
```cs
134164
var config = Configuration.Default;

0 commit comments

Comments
 (0)