-
Notifications
You must be signed in to change notification settings - Fork 151
[Feature Request] No ability to refresh authentication token #993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I believe the problem lies in the fact that the authToken is a constant object, and not something that is reevaluated. In Java, the authToken comes from InternalAuthToken.toMap() method, so, |
We could achieve this by allowing an async function to be passed in as the auth token. // neo4j-driver/src/index.js
if (authToken.constructor.name !== "AsyncFunction") {
// Sanitize authority token. Nicer error from server when a scheme is set.
authToken = authToken || {};
authToken.scheme = authToken.scheme || "none";
}
// Use default user agent or user agent specified by user.
config.userAgent = config.userAgent || USER_AGENT;
const address = ServerAddress.fromUrl(parsedUrl.hostAndPort); // bolt-connection/src/connection/connection-channel.js
_initialize (userAgent, authToken) {
const self = this
return new Promise(async (resolve, reject) => {
let token = authToken
if (authToken.constructor.name === 'AsyncFunction') {
token = await authToken()
}
this._protocol.initialize({
userAgent,
token,
onError: (err) => reject(err), // core/src/auth.ts
const auth = {
...,
awsv4: async (cb: () => Promise<any>) => {
return await cb()
}
}
With that we can pass in this as the auth token and fix the issue neo4j.driver(url, async () => {
const credentials = await signedHeader()
let authToken = {
scheme: 'basic',
realm: 'realm',
principal: 'username',
credentials: credentials,
}
return authToken
}) @bigmontz is this a change that would be allowed to merge? |
@germangamboa95, we are evaluating the solution for the feature request internally. We are drafting some designs, whenever I have some concrete I will post here. |
@bigmontz any update on this ? :) |
@cptflammin, we already started the development. |
**⚠️ This API is released as preview.** This changes introduce two ways of changing the connection credentials in a driver instance, each of them solving a different use case. ### Token Expiration / Change Credentials for the whole driver instance This use case is related to the issue #993 in the repository. For solving this, the driver is now able to receive a `AuthTokenManager` in the driver creation. This interface enables the user code provide new auth tokens to the driver and be notified by token expiration failures. For simplifying the usage, the driver also provides a default implementation of `AuthTokenManager` which can be created with `neo4j.temporalAuthDataManager` and receives a function for renewing the auth token as parameters. Example: ```typescript import neo4j, { AuthToken } from 'neo4j-driver' /** * Method called whenever the driver needs to refresh the token. * * The refresh will happen if the driver is notified by the server * about a token expiration or if the `Date.now() > tokenData.expiry` * * Important, the driver will block all the connections creation until * this function resolves the new auth token. */ async function fetchAuthTokenFromMyProvider () { const bearer: string = await myProvider.getBearerToken() const token: AuthToken = neo4j.auth.bearer(bearer) const expiration: Date = myProvider.getExpiryDate() return { token, // if expiration is not provided, // the driver will only fetch a new token when a failure happens expiration } } const driver = neo4j.driver( 'neo4j://localhost:7687', neo4j.expirationBasedAuthTokenManager({ getAuthData: fetchAuthTokenFromMyProvider }) ) ``` ### User Switching In this scenario, different credentials can be configured in a session providing a way for change the user context for the session. For using this feature, it needed to check if your server supports session auth by calling `driver.supportsSessionAuth()`. Example: ```typescript import neo4j from 'neo4j-driver' const driver = neo4j.driver( 'neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'password') ) const sessionWithUserB = driver.session({ database: 'neo4j', auth: neo4j.auth.basic('userB', 'userBpassword') }) try { // run some queries as userB const result = await sessionWithUserB.executeRead(tx => tx.run('RETURN 1')) } finally { // close the session as usual await sessionWithUserB.close() } ``` **⚠️ This API is released as preview.**
Problem solved by #1050. |
I am unsure whether to call this a bug or a feature request. We're using opencypher with AWS Neptune and want to use the neo4j driver with the bolt protocol to allow us in the future to make an easier switch to neo4j enterprise. We are generating an AWS V4 Signature and passing it in as a basic auth to the driver.
Unfortunately, we can't figure out a way to gracefully handle the signature expiring (whether it's 5m or 24h). I imagine a lot of things would be involved in handling this gracefully (lost queries, reconnecting, transactions, etc), we would love for the driver to be able to handle the regeneration of the signature for us.
Thanks in advance!
Steps to reproduce
Here is the code that we've used to generate the neo4j driver w/ an AWS V4 Signature:
Expected behavior
Driver should be able to know when a token expires and have stored functionality to regenerate specific token.
Actual behavior
Driver fails to authenticate and all subsequent requests fail
The text was updated successfully, but these errors were encountered: