A C# implementation of the "Authorization" scheme of the IETF Internet-Draft Signing HTTP Messages.
It contains:
- HTTP request signing services.
- HTTP request signature verification services.
- Authentication middleware for ASP.NET Core applications.
- Authentication middleware for OWIN applications.
- Extensions for storing known clients in memory.
- Extensions for storing known clients in MongoDb.
See wiki for further details.
When communicating over the Internet using the HTTP protocol, it can be desirable for a server or client to authenticate the sender of a particular message. It can also be desirable to ensure that the message was not tampered with during transit. The Signing HTTP Messages Internet-Draft describes a way for servers and clients to simultaneously add authentication and message integrity to HTTP messages by using a digital signature.
This repository is a C# implementation of that specification.
When signing a request message, an Authorization header is set in a http request. Using this header, the server can verify that it is sent by the known client, and that the content has not been tampered with.
The signing will result in a request header that will look like:
Authorization: Signature keyId="e0e8dcd638334c409e1b88daf821d135",algorithm="hs2019",created=1584806516,expires=1584806576,headers="(request-target) dalion-app-id date digest",nonce="38brRy8BLUajMbUqWumXPg",signature="DUKQVjiirGMMaMOy9qIwKMro46R3BlLsvUQkw1/8sKQ="
When configured, a RequestSignerFactory is registered in your composition root. Example usage:
public class SignRequestService {
private readonly IHttpClient<SignRequestService> _httpClient;
private readonly IRequestSignerFactory _requestSignerFactory;
...
public async Task<HttpResponseMessage> SendSignedRequest(HttpRequestMessage request, CancellationToken cancellationToken) {
var requestSigner = _requestSignerFactory.CreateFor(keyId: "f1ed1eff7ca4429abe1abbbe9ae6419a");
await requestSigner.Sign(request);
return await _httpClient.SendAsync(request, cancellationToken);
}
}
And verification can be done server-side:
public class HttpRequestSignatureParser {
private readonly IRequestSignatureVerifier _requestSignatureVerifier;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ILogger<HttpRequestSignatureParser> _logger;
...
public async Task Verify(HttpRequest request) {
var verificationResult = await _requestSignatureVerifier.VerifySignature(request);
var httpContext = _httpContextAccessor.HttpContext;
if (verificationResult is RequestSignatureVerificationResultFailure failure) {
_logger.LogWarning(failure.SignatureVerificationException, "Request signature verification failed. See exception for details.");
httpContext.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
}
else if (verificationResult is RequestSignatureVerificationResultSuccess success) {
_logger.LogInformation("Successfully verified signature for identity {0}.", success.Principal.Identity.Name);
httpContext.User = success.Principal;
}
}
}
There is OWIN and ASP.NET Core middleware available too, for easy integration.
For more details and options, see the Wiki.
See Wiki.
If you've got value from any of the content which I have created, but pull requests are not your thing, then I would also very much appreciate your support by buying me a coffee.