Giter Club home page Giter Club logo

httpmessagesigning's People

Contributors

dacspiir avatar davidlievrouw avatar zacuke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

httpmessagesigning's Issues

Getting a Client from the MongoClientStore does not return null, but an instance without any property values filled in

Since v5.3.0, some KeyId values are prohibited, when creating a Client. This was needed to avoid having a Client in MongoDB with the reserved id _version.

First of all, this limitation only makes sense in the context of MongoDB. We should move that restriction there, and not have it as a general restriction for all implementors.

Secondly, when getting a Client from Mongo with the id _version, it returns an instance, but no property values are filled in. So it returns an invalid instance. This should be avoided. More specifically, the MongoClientStore should return null when requesting a client with a prohibited id.

Disabling nonce does not work

Setting EnableNonce = false in the SigningSetting does not disable the nonce.

I think the issue here is that the field EnableNonce gets not copied in the Clone method.

Invalid request-target according to the RFC

According to the RFC (https://tools.ietf.org/html/draft-cavage-http-signatures-12#section-2.3), the request-target should contain the request parameters, which are excluded by the library in the Extensions.HttpRequestMessage class (https://github.com/DavidLievrouw/HttpMessageSigning/blob/90bf3c77818855c092063af6ac363fa3e98fa9d7/src/HttpMessageSigning/Extensions.HttpRequestMessage.cs).

I believe this should be the fix:
var requestForSigning = new HttpRequestForSigning { Method = httpRequestMessage.Method, RequestUri = httpRequestMessage.RequestUri.IsAbsoluteUri ? httpRequestMessage.RequestUri.PathAndQuery.UrlDecode() : httpRequestMessage.RequestUri.OriginalString.UrlDecode() };

MongoDb ?authSource=admin is not supported.

When specifying the following connection string:

mongodb://john.doe:p@ssw0rd@localhost:27017/Authentication?authSource=admin

Every database operation is performed on the admin database, not on the Authentication database.

Update to adhere to 04 version of Internet Draft

A new version of the Internet Draft has been published.

Noticeable changes, impacting this library:

  • The (created), (expires) and (request-target) pseudo-headers have been replaced by specialty fields @request-target and @signature-params.
    • The @signature-params specialty field should be part of the composed signature string. This includes the values of the legacy (created) and (expires) pseudo-headers.
  • The signature used to be added to the Authorization-header of the request message. In the new spec, a combination of Signature and Signature-Input headers are used instead. This will allow for multiple signatures in the future.
  • HTTP header fields must use LOWERCASED field names, not case-insensitive ones.
  • Simplify combination of encryption and hashing algorithms to those from the draft, and specify them in the alg field:
    • rsa-pss-sha512
    • rsa-v1_5-sha256
    • hmac-sha256
    • ecdsa-p256-sha256

As you can see, major breaking changes here.
We will need to provide an upgrade path for existing consumers, especially concerning the enc/hash algorithm combinations.

Other changes will be handled in separate issues:

Multi-target packages

We now target:

  • .NET Standard 2.0: Core, Signing, Verification and MongoDb packages.
  • .NET Core 2.2: ASP.NET Core package
  • .NET Core 3.1: ASP.NET Core package
  • .NET Framework 4.7.2: Owin package

Investigate if we can target a lower .NET Standard version.
Add more specific target frameworks, as specified in the NuGet guidelines.

This change might require a major version bump, because inner dependencies might change.

Introduce DI builder pattern

We now perform DI registrations using extension methods for IServiceCollection. A common practice is to provide a "builder" (e.g. IHttpMessageSigningVerificationBuilder and IHttpMessageSigningBuilder).

This makes it cleaner and more intuitive to perform DI registrations:

services
    .AddHttpMessageSigning()
    .UseKeyId(...)
    .UseSigningSettings(...);
services
    .AddHttpMessageSignatureVerification()
    .UseInMemoryClientStore()
    .UseMongoNonceStore(provider => new MongoDbNonceStoreSettings {
        ConnectionString = "mongodb://localhost:27017/HttpMessageSigningDb",
        CollectionName = "client_nonces"
    })
    .UseClient(...)
    .UseClient(...);

Because we will change the return type of AddHttpMessageSigning and AddHttpMessageSignatureVerification, this is considered to be a breaking change.

Add support for a SqlServer-backed IClientStore

We now support InMemory and MongoDB implementations for IClientStore. To make the verification library more accessible, and lower the threshold for users, we should provide a SqlServer-backed IClientStore out-of-the-box.

Invalidate Client cache when inserting or updating

The .DecorateWithCaching-method adds a decorator with caching. That cache timeout is configurable.

If you set the cache timeout to TimeSpan.Zero, Client caching is disabled.

However, when calling .Register, that cache is not invalidated. E.g. when updating a SignatureAlgorithm for a client, it will take the [cacheExpiration] amount of time before that change is reflected upon authentication.

Also, for implementers of a custom IClientStore, it could be useful to have the ability to invalidate the cache.

  • Invalidate the cache when registering a new client.
  • Allow invalidating the cache by implementers of a client store.

Also, make sure that you Dispose an evicted client.

Make (request-target) escaping option settable

In v5.0.1, the escaping is used following the rules from RFC 3986. To facilitate compatibility with other libraries, this behavior should be configurable.

Suggestion is to add property SigningSettings.RequestTargetEscaping with the following options:

  • RFC 3986 (default)
  • RFC 2396
  • OriginalString
  • Unescaped

Use this setting in the extension method ToHttpRequestForSigning.

This should also be an option for a verification Client. We can add the same property there, and use it in ToHttpRequestForVerification.

Regain performance lost after v4.1.1

The hotfix 4.1.1 caused a certain amount performance loss during both signing and verifying, because we are not able to reuse hash algorithms during concurrent requests. We should find a way to gain some/all of it back.

Some ideas:

  • Hash/HMAC algorithm pools
    • Lease an algorithm per thread, return to pool when the signing/verifying is finished
  • Dispose used hash/HMAC algorithms in the background
  • Profile and find performance elsewhere

It is not possible to manipulate SigningString during event handling

This is the signature of the OnSigningStringComposed event:

public Func<HttpRequestMessage, string, Task> OnSigningStringComposed { get; set; } = (requestToSign, signingString) => Task.CompletedTask;

When modifying the signingString value in the event handler, this change gets lost. This argument needs to be passed by ref.

Nonce not required to be included in list of required headers

https://tools.ietf.org/html/draft-ietf-httpbis-message-signatures-04#section-2.1 seems to indicate that headers included in the signature should be listed as comma separate list.

We are able to create signatures that do not list nonce as a required header in the headers= property.

Is this a bug in the library? Since it requires nonce to be a part of the signature, shouldn't it also be a part of the headers= property? Or am I misunderstanding something?

Add targets for net5.0

Add target frameworks for net5.0 in the solution.
Run benchmarks and validate that the behavior is the same.

You should not need to mark X509Certificate2 object as Exportable to use them for signing

To use an X509Certificate2 object for a signature algorithm, for signing, you need to declare it as Exportable.

new X509Certificate2(
  "mycert.pfx",
  "pwd",
  X509KeyStorageFlags.Exportable)

This is actually not needed, if we would call the correct constructor internally. It's just a wiring problem.

You should be able to use an X509Certificate2 object for signing, as follows:

new X509Certificate2(
  "mycert.pfx",
  "pwd")

Fix support for MongoDB.Driver v2.19.0

When using MongoDB.Driver v2.19.0, serialization errors occur.

MongoDB.Driver.Linq.ExpressionNotSupportedException: Expression not supported: Convert(r.Id, KeyId) because conversion to Dalion.HttpMessageSigning.KeyId is not supported.
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ConvertExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, UnaryExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.UnaryExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, UnaryExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.BinaryExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, BinaryExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToFilterTranslators.ExpressionToFilterTranslator.TranslateUsingAggregationOperators(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToFilterTranslators.ExpressionToFilterTranslator.Translate(TranslationContext context, Expression expression, Boolean exprOk)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToFilterTranslators.ExpressionToFilterTranslator.TranslateLambda(TranslationContext context, LambdaExpression lambdaExpression, IBsonSerializer parameterSerializer, Boolean asRoot)
   at MongoDB.Driver.Linq.Linq3Implementation.LinqProviderAdapterV3.TranslateExpressionToFilter[TDocument](Expression`1 expression, IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.ExpressionFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)
   at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
   at MongoDB.Driver.MongoCollectionImpl`1.FindAsync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass48_0`1.<FindAsync>b__0(IClientSessionHandle session)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
   at Dalion.HttpMessageSigning.Verification.MongoDb.MongoDbClientStore.Get(KeyId clientId)
   at Dalion.HttpMessageSigning.Verification.CachingClientStore.Get(KeyId clientId)

I suspect that the implicit cast from KeyId to string no longer works.

Pass a simple string to the FilterBuilder instead.

hs2019 is not supported

The current version of the draft specification (https://tools.ietf.org/html/draft-cavage-http-signatures-12) enforces setting the algorithm parameter to "hs2019" effectively hiding the real used algorithm. All other options for the algorithm parameter are deprecated in Appendix E.2.

This library should support setting the "hs2019". Note that this also changes the semantics of the draft at all positions where they explicitly state rules based on the algorithm parameter.

Furthermore for verification the library should support to provide the verifier with the real used algorithm based on the keyId value (i.e. some sort of callback) so that it can use this algorithm for verification if algorithm=hs2019.

Consider changing casing in MongoDb package To MongoDB

The official name, as used here is MongoDB, not MongoDb.

  • Update package, namespaces and source file names.
  • Make sure that we don't break the NuGet package, published on nuget.org.

Is it worth the risk?
Should we publish a new package instead, referring the old one to the new one?

Invalid client should not throw exception during validation

When an invalid client is specified in the authorization header, an exception is thrown that is caught by the RequestSignatureVerifier. A verification failure is then returned to the client.

This should not be an Exception. It's a known code path. Handle it with a branch statement instead of an exception. Quite a big performance gain for failed verifications, imo.

Add support for a FileSystem-backed IClientStore

We now support InMemory, SqlServer and MongoDB implementations for IClientStore. To make the verification library more accessible, and lower the threshold for users, we should provide a FileSystem-backed IClientStore out-of-the-box.

Instantiate IRequestSignerFactory without DI

Currently, the only way to instantiate an IRequestSignerFactory is by using DI (after reading the wiki). I also noticed the classes are marked as internal which prevents my from instantiating them manually.

I prefer not to introduce DI frameworks in my application for one library.

Is this something you would consider changing in future versions?

Client constructor is getting convoluted

The constructor of the Client class has more and more arguments, as features are being added, It's getting convoluted and feels like a code smell.

Create a factory or factory methods to more easily create Client instances, specifying only what deviates from the default.

Client.Create and a bunch of overloads.

Request-target should not be URL decoded

There should be an additional (small) fix. Why is the requestUri URL decoded? It's not necessary, if the URL is encoded it should be taken this way otherwise the verification process fails.

So this is the change:
var requestForSigning = new HttpRequestForSigning { Method = httpRequestMessage.Method, RequestUri = httpRequestMessage.RequestUri.IsAbsoluteUri ? httpRequestMessage.RequestUri.PathAndQuery : httpRequestMessage.RequestUri.OriginalString.Split('#')[0] };

Originally posted by @dieterde in #10 (comment)

Use `IAuthenticationHeaderExtractor` in `SignedRequestAuthenticationHandler`

Currently, we can register a custom IAuthenticationHeaderExtractor for cases where the signature is not in the Authorization header.

Unfortunately, the SignedRequestAuthenticationHandler is currently hard-coded to expect an Authorization header explicitly - even though the actual verification uses the custom extractor.

Can these pre-conditions (lines 23, 24) be replaced with a call to the IAuthenticationHeaderExtractor instead?

Create super-duper-happy-path in wiki

The most simple example of signing and verifying in README and the wiki is actually already rather detailed. We should write down a very simple usage example, avoiding the advanced options, and ASP.NET Core or OWIN middleware.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.