neo4j / neo4j-dotnet-driver

Neo4j Bolt driver for .NET
Apache License 2.0
227 stars 69 forks source link

[Feature Request] Ability to refresh auth token #664

Closed morningpuddle closed 10 months ago

morningpuddle commented 1 year ago

To help us understand your issue, please specify important details, primarily:

We are using OpenCypher with AWS Neptune as the endpoint, with Neo4j DotNet Driver with bolt protocol. We generate AWS V4 signature and pass it in as a basic auth to the driver. The request is signed using temporary credentials which expires in 5 minutes.

With following 3 files (attached with .txt rather than .cs extension, since github doesn't allow uploading .cs files):

and dependencies

Neo4j.Driver=4.3.0
AWSSDK.Core=3.7.102.1

I want to be able to mint a new signature when the new connection is being created after lifetime has been reached (eg. after 30 min for below case; I believe it's 1 hour by default when not specified), such that not the the old expired signature is used.

# in HelloWorldExample file
        public HelloWorldExample()
        {
            var authToken = new NeptuneAuthToken(AccessKey, SecretKey, Region).GetAuthToken(Host);
            _driver = GraphDatabase.Driver(Url, authToken, o => o.WithMaxConnectionLifetime(TimeSpan.FromMinutes(30)).WithEncryptionLevel(EncryptionLevel.Encrypted));
        }

The first generated signature is getting used for authentication of the new connection, such that it fails with:

# then fails 
< 
Unhandled exception. Neo4j.Driver.DatabaseException: "Unexpected server exception 'Signature expired: 20221214T182326Z is now earlier than 20221214T182327Z (20221214T182827Z - 5 min.)'"
   at Neo4j.Driver.Internal.Connector.PooledConnection.OnErrorAsync(Exception error)
   at Neo4j.Driver.Internal.Connector.DelegatedConnection.TaskWithErrorHandling(Func`1 task)
   at Neo4j.Driver.Internal.ConnectionPool.CreateNewPooledConnectionAsync(CancellationToken cancellationToken)
   at Neo4j.Driver.Internal.ConnectionPool.CreateNewPooledConnectionAsync(CancellationToken cancellationToken)
   at Neo4j.Driver.Internal.ConnectionPool.CreateNewConnectionOrGetIdleAsync(CancellationToken cancel

I see that the Java driver provides a way to avoid this problem by exposing a toMap method, that is called to obtain the token. This method can be overridden in a subclass as shown here.

The AuthTokenExtensions has #AsDictionary method, where one could create a class that extends AuthToken and override the getter method to mint a new signature.

However, AuthToken is an internal class, so it can't be extended.

Above is one idea I got. I am open to other suggestions.

thelonelyvulpes commented 1 year ago

@morningpuddle We are evaluating a solution for the feature request internally. We are drafting some designs, whenever I have some concrete I will post here.

hanlong-chen-1047 commented 1 year ago

Is there any update on when this will be addressed?

AndyHeap-NeoTech commented 1 year ago

The current status of the work can be found in the conversation linked to above, the comment is here: Feature Request

samuel-chabot commented 11 months ago

Is there any update for the dotnet driver ? The comment above only specify for the go driver but I can't find any tracking for the dotnet one

AndyHeap-NeoTech commented 11 months ago

In the latest version of the driver (5.13) you will find in the preview namespace additions that enable: 1) Auth rotation, replacing the authentication information in the driver without having to create a new driver object 2) Session auth/user switching, using specific auth information for the duration of a session

You can find more information here: https://github.com/neo4j/neo4j-dotnet-driver/discussions/705

Note: AuthTokenManagers.ExpirationBased is now named AuthTokenManagers.Bearer.

This functionality is going to be coming out of Preview in the next release 5.14 at the end of the month.