Skip to content

Commit

Permalink
Session-scoped authentication (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefano-ottolenghi authored Nov 14, 2024
1 parent 849d874 commit b3d4f38
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 47 deletions.
25 changes: 19 additions & 6 deletions go-manual/modules/ROOT/pages/query-simple.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -227,24 +227,37 @@ In other words, there is no guarantee that a write query submitted in read mode


[#impersonation]
[role=label--new-5.14]
=== Run queries as a different user

You can execute a query under the security context of a different user with the callback `neo4j.ExecuteQueryWithImpersonatedUser("<somebodyElse>")`, specifying the name of the user to impersonate.
For this to work, the user under which the `DriverWithContext` object
was created needs to have the link:{neo4j-docs-base-uri}/cypher-manual/current/administration/access-control/dbms-administration#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `DriverWithContext` object.
You can execute a query through a different user with the configuration callback `neo4j.ExecuteQueryWithAuthToken()`.
Switching user at the query level is cheaper than creating a new `DriverWithContext` object.
The query is then run within the security context of the given user (i.e., home database, permissions, etc.). +
Query-scoped authentication a server version >= 5.8.

[source, go]
----
queryAuth := neo4j.BasicAuth("somebodyElse", "theirPassword", "")
neo4j.ExecuteQuery(ctx, driver,
"MATCH (p:Person) RETURN p.name",
nil,
neo4j.EagerResultTransformer,
neo4j.ExecuteQueryWithDatabase("neo4j"),
neo4j.ExecuteQueryWithImpersonatedUser("<somebodyElse>"))
neo4j.ExecuteQueryWithAuthToken(queryAuth))
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e. home database, permissions, etc.).
The callback `neo4j.ExecuteQueryWithImpersonatedUser()` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, go]
----
neo4j.ExecuteQuery(ctx, driver,
"MATCH (p:Person) RETURN p.name",
nil,
neo4j.EagerResultTransformer,
neo4j.ExecuteQueryWithDatabase("neo4j"),
neo4j.ExecuteQueryWithImpersonatedUser("<somebodyElse>"))
----


== A full example
Expand Down
24 changes: 18 additions & 6 deletions go-manual/modules/ROOT/pages/transactions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -494,21 +494,33 @@ Similar remarks hold for the `.ExecuteRead()` and `.ExecuteWrite()` methods.


[#impersonation]
=== Run queries as a different user (impersonation)
[role=label--new-5.14]
=== Run queries as a different user

You can execute a query under the security context of a different user with the configuration parameter `ImpersonatedUser`, specifying the name of the user to impersonate.
For this to work, the user under which the `DriverWithContext` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `DriverWithContext` object.
You can execute a query through a different user with the configuration option `Auth`.
Switching user at the session level is cheaper than creating a new `DriverWithContext` object.
Queries are then run within the security context of the given user (i.e., home database, permissions, etc.). +
Session-scoped authentication requires a server version >= 5.8.

[source, go]
----
sessionAuth := neo4j.BasicAuth("somebodyElse", "theirPassword", "")
session := driver.NewSession(ctx, neo4j.SessionConfig{
DatabaseName: "neo4j",
ImpersonatedUser: "<somebodyElse>",
Auth: &sessionAuth,
})
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e. home database, permissions, etc.).
The option `ImpersonatedUser` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, go]
----
session := driver.NewSession(ctx, neo4j.SessionConfig{
DatabaseName: "neo4j",
ImpersonatedUser: "<somebodyElse>",
})
----


== Transaction configuration
Expand Down
27 changes: 22 additions & 5 deletions java-manual/modules/ROOT/pages/query-simple.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -234,25 +234,42 @@ In other words, there is no guarantee that a write query submitted in read mode


[#impersonation]
[role=label--new-5.18]
=== Run queries as a different user

You can execute a query under the security context of a different user with the method `.withImpersonatedUser("<username>")`, specifying the name of the user to impersonate.
For this to work, the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/cypher-manual/current/administration/access-control/dbms-administration#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `Driver` object.
You can execute a query through a different user with the method `.withAuthToken()`.
Switching user at the query level is cheaper than creating a new `Driver` object.
The query is then run within the security context of the given user (i.e., home database, permissions, etc.). +
Query-scoped authentication a server version >= 5.8.

[source, java, test-skip]
----
// import org.neo4j.driver.AuthTokens;
// import org.neo4j.driver.QueryConfig;
var authToken = AuthTokens.basic("somebodyElse", "theirPassword");
var result = driver.executableQuery("MATCH (p:Person) RETURN p.name")
.withConfig(QueryConfig.builder()
.withDatabase("neo4j")
.withImpersonatedUser("somebodyElse")
.withAuthToken(authToken)
.build())
.execute();
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e. home database, permissions, etc.).
The method `.withImpersonatedUser()` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, java, test-skip]
----
// import org.neo4j.driver.QueryConfig;
var result = driver.executableQuery("MATCH (p:Person) RETURN p.name")
.withConfig(QueryConfig.builder()
.withDatabase("neo4j")
.withImpersonatedUser("somebodyElse")
.build())
.execute();
----


== A full example
Expand Down
32 changes: 25 additions & 7 deletions java-manual/modules/ROOT/pages/transactions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -447,25 +447,43 @@ Similar remarks hold for the `.executeRead()` and `.executeWrite()` methods.


[#impersonation]
=== Run queries as a different user (impersonation)
[role=label--new-5.18]
=== Run queries as a different user

You can execute a query under the security context of a different user with the method `.withImpersonatedUser("<username>")`, specifying the name of the user to impersonate.
For this to work, the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `Driver` object.
You can execute a query through a different user by providing an link:https://neo4j.com/docs/api/java-driver/current/org.neo4j.driver/org/neo4j/driver/AuthTokens.html[AuthToken] as third parameter upon session creation.
Switching user at the session level is cheaper than creating a new `Driver` object.
Queries are then run within the security context of the given user (i.e., home database, permissions, etc.). +
Session-scoped authentication requires a server version >= 5.8.

[source, java]
----
// import org.neo4j.driver.AuthTokens;
// import org.neo4j.driver.Session;
// import org.neo4j.driver.SessionConfig;
var authToken = AuthTokens.basic("somebodyElse", "theirPassword");
var session = driver.session(
Session.class,
SessionConfig.builder()
.withDatabase("neo4j")
.build(),
authToken
);
----

The method `.withImpersonatedUser()` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, java]
----
// import org.neo4j.driver.SessionConfig;
// import org.neo4j.driver.RoutingControl;
var session = driver.session(SessionConfig.builder()
.withDatabase("neo4j")
.withImpersonatedUser("somebodyElse")
.build());
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e. home database, permissions, etc.).


== Transaction configuration

Expand Down
2 changes: 1 addition & 1 deletion javascript-manual/modules/ROOT/pages/connect.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ You connect to a database by creating a <<Driver>> object and providing a URL an
let driver
try {
driver = neo4j.driver(URI, neo4j.auth.basic(USER, PASSWORD)) // <1>
driver = neo4j.driver(URI, neo4j.auth.basic(USER, PASSWORD)) // <1>
const serverInfo = await driver.getServerInfo() // <2>
console.log('Connection established')
console.log(serverInfo)
Expand Down
25 changes: 20 additions & 5 deletions javascript-manual/modules/ROOT/pages/query-simple.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -210,25 +210,40 @@ In other words, there is no guarantee that a write query submitted in read mode


[#impersonation]
[role=label--new-5.14]
=== Run queries as a different user

You can execute a query under the security context of a different user with the parameter `impersonatedUser`, specifying the name of the user to impersonate.
For this to work, the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/cypher-manual/current/administration/access-control/dbms-administration#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `Driver` object.
You can execute a query through a different user with the configuration parameter `auth`.
Switching user at the query level is cheaper than creating a new `Driver` object.
The query is then run within the security context of the given user (i.e., home database, permissions, etc.). +
Query-scoped authentication a server version >= 5.8.

[source, javascript, test-skip]
----
await driver.executeQuery(
'MATCH (p:Person) RETURN p.name',
{},
{
impersonatedUser: 'somebodyElse',
auth: neo4j.auth.basic('somebodyElse', 'theirPassword'),
database: 'neo4j'
}
)
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e. home database, permissions, etc.).
The parameter `impersonatedUser` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, javascript, test-skip]
----
await driver.executeQuery(
'MATCH (p:Person) RETURN p.name',
{},
{
impersonatedUser: 'somebodyElse',
database: 'neo4j'
}
)
----


== A full example
Expand Down
23 changes: 17 additions & 6 deletions javascript-manual/modules/ROOT/pages/transactions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -330,21 +330,32 @@ Similar remarks hold for the `.executeRead()` and `.executeWrite()` methods.


[#impersonation]
=== Run queries as a different user (impersonation)
[role=label--new-5.14]
=== Run queries as a different user

You can execute a query under the security context of a different user with the parameter `impersonatedUser`, specifying the name of the user to impersonate.
For this to work, the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `Driver` object.
You can execute a query through a different user with the configuration parameter `auth`.
Switching user at the session level is cheaper than creating a new `Driver` object.
Queries are then run within the security context of the given user (i.e., home database, permissions, etc.). +
Session-scoped authentication requires a server version >= 5.8.

[source, javascript]
----
const session = driver.session({
database: 'neo4j',
impersonatedUser: 'somebodyElse'
auth: neo4j.auth.basic('somebodyElse', 'theirPassword')
})
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e., home database, permissions, etc.).
The parameter `impersonatedUser` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, javascript]
----
const session = driver.session({
database: 'neo4j',
impersonatedUser: 'somebodyElse'
})
----


== Transaction configuration
Expand Down
22 changes: 17 additions & 5 deletions python-manual/modules/ROOT/pages/query-simple.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -216,22 +216,34 @@ In other words, there is no guarantee that a write query submitted in read mode


[#impersonation]
[role=label--new-5.14]
=== Run queries as a different user

You can execute a query under the security context of a different user with the parameter `impersonated_user_`, specifying the name of the user to impersonate.
For this to work, the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/cypher-manual/current/administration/access-control/dbms-administration#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `Driver` object.
You can execute a query through a different user with the parameter `auth_`.
Switching user at the query level is cheaper than creating a new `Driver` object.
The query is then run within the security context of the given user (i.e., home database, permissions, etc.). +
Query-scoped authentication a server version >= 5.8.

[source, python, test-skip]
----
driver.execute_query(
"MATCH (p:Person) RETURN p.name",
impersonated_user_="somebody_else",
auth_=("somebody_else", "their_password"),
database_="neo4j",
)
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e. home database, permissions, etc.).
The parameter `impersonated_user_` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, python, test-skip]
----
driver.execute_query(
"MATCH (p:Person) RETURN p.name",
impersonated_user_="somebody_else",
database_="neo4j",
)
----


=== Transform query result
Expand Down
23 changes: 17 additions & 6 deletions python-manual/modules/ROOT/pages/transactions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -410,23 +410,34 @@ Similar remarks hold for the `.executeRead()` and `.executeWrite()` methods.


[#impersonation]
=== Run queries as a different user (impersonation)
[role=label--new-5.14]
=== Run queries as a different user

You can execute a query under the security context of a different user with the parameter `impersonated_user`, specifying the name of the user to impersonate.
For this to work, the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].
Impersonating a user is cheaper than creating a new `Driver` object.
You can execute a query through a different user with the parameter `auth`.
Switching user at the session level is cheaper than creating a new `Driver` object.
Queries are then run within the security context of the given user (i.e., home database, permissions, etc.). +
Session-scoped authentication requires a server version >= 5.8.

[source, python]
----
with driver.session(
database="neo4j",
impersonated_user="somebody_else"
auth=("somebody_else", "their_password")
) as session:
...
----

When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (i.e., home database, permissions, etc.).
The parameter `impersonated_user` provides a similar functionality, and is available in driver/server versions >= 4.4.
The difference is that you don't need to know a user's password to impersonate them, but the user under which the `Driver` was created needs to have the link:{neo4j-docs-base-uri}/operations-manual/current/authentication-authorization/dbms-administration/#access-control-dbms-administration-impersonation[appropriate permissions].

[source, python]
----
with driver.session(
database="neo4j",
impersonated_user="somebody_else"
) as session:
...
----

== Close sessions

Expand Down

0 comments on commit b3d4f38

Please sign in to comment.