Skip to content

zacuke/HttpMessageSigning

 
 

Repository files navigation

HttpMessageSigning

A C# implementation of the "Authorization" scheme of the IETF Internet-Draft Signing HTTP Messages.

Build status Coverage Status License: MIT

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.

Motivation

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.

NuGet

Package NuGet status
Dalion.HttpMessageSigning NuGet Status
Dalion.HttpMessageSigning.Signing NuGet Status
Dalion.HttpMessageSigning.Verification NuGet Status
Dalion.HttpMessageSigning.Verification.AspNetCore NuGet Status
Dalion.HttpMessageSigning.Verification.Owin NuGet Status
Dalion.HttpMessageSigning.Verification.MongoDb NuGet Status

Basics

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 options = new SignedRequestAuthenticationOptions {
            Realm = "Sample application",
            OnSignatureParsed = (httpRequest, signature) => {
                _logger.LogDebug("Parsed signature for client with key '{0}'.", signature.KeyId);
                return Task.CompletedTask;
            }
        };
        var verificationResult = await _requestSignatureVerifier.VerifySignature(request, options);

        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.

Documentation

See Wiki.

Support

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.

Buy Me A Coffee


"Anybody can make something that works. Software craftsmanship is the ability to keep it understandable, maintainable and extensible."

About

Adds authentication and message integrity to HTTP messages by using a digital signature.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 98.4%
  • Batchfile 1.6%