Skip to content

Commit 5796340

Browse files
authored
Add guide on impersonation and user switching (#24)
1 parent 0efbf62 commit 5796340

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

modules/ROOT/content-nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
*** xref:authentication-and-authorization/configuration.adoc[]
5353
*** xref:authentication-and-authorization/authentication.adoc[]
5454
*** xref:authentication-and-authorization/authorization.adoc[]
55+
*** xref:authentication-and-authorization/impersonation-and-user-switching.adoc[]
5556

5657
** xref:introspector.adoc[Introspector]
5758

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
= Impersonation and user switching
2+
3+
Impersonation and user switching are features of the Neo4j database and driver which allow for query execution in a different context to the initial connection.
4+
5+
== Impersonation
6+
7+
Impersonation still authenticates with the database as the original configured user, but runs the query in the context of an impersonated user.
8+
When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (home database, permissions, etc.).
9+
10+
An example of how to impersonate a different user per request can be found below. In this example, the user to impersonate is taken from a HTTP header `User`:
11+
12+
.TypeScript
13+
[%collapsible]
14+
====
15+
[source, typescript, indent=0]
16+
----
17+
import { ApolloServer } from "@apollo/server";
18+
import { startStandaloneServer } from "@apollo/server/standalone";
19+
import { Neo4jGraphQL, Neo4jGraphQLContext } from "@neo4j/graphql";
20+
import neo4j from "neo4j-driver";
21+
22+
const typeDefs = `#graphql
23+
type Movie {
24+
title: String!
25+
}
26+
`;
27+
28+
const driver = neo4j.driver(
29+
"neo4j://localhost:7687",
30+
neo4j.auth.basic("neo4j", "password")
31+
);
32+
33+
const neo4jgraphql = new Neo4jGraphQL({
34+
typeDefs,
35+
driver,
36+
});
37+
38+
const schema = await neo4jgraphql.getSchema();
39+
40+
const server = new ApolloServer<Neo4jGraphQLContext>({
41+
schema,
42+
});
43+
44+
const { url } = await startStandaloneServer(server, {
45+
// Your async context function should async and return an object
46+
context: async ({ req }) => ({
47+
sessionConfig: {
48+
impersonatedUser: req.headers.user,
49+
},
50+
}),
51+
});
52+
53+
console.log(`🚀 Server ready at: ${url}`);
54+
----
55+
====
56+
57+
.JavaScript
58+
[%collapsible]
59+
====
60+
[source, javascript, indent=0]
61+
----
62+
import { ApolloServer } from "@apollo/server";
63+
import { startStandaloneServer } from "@apollo/server/standalone";
64+
import { Neo4jGraphQL } from "@neo4j/graphql";
65+
import neo4j from "neo4j-driver";
66+
67+
const typeDefs = `#graphql
68+
type Movie {
69+
title: String!
70+
}
71+
`;
72+
73+
const driver = neo4j.driver(
74+
"neo4j://localhost:7687",
75+
neo4j.auth.basic("neo4j", "password")
76+
);
77+
78+
const neo4jgraphql = new Neo4jGraphQL({
79+
typeDefs,
80+
driver,
81+
});
82+
83+
const schema = await neo4jgraphql.getSchema();
84+
85+
const server = new ApolloServer({
86+
schema,
87+
});
88+
89+
const { url } = await startStandaloneServer(server, {
90+
// Your async context function should async and return an object
91+
context: async ({ req }) => ({
92+
sessionConfig: {
93+
impersonatedUser: req.headers.user,
94+
},
95+
}),
96+
});
97+
98+
console.log(`🚀 Server ready at: ${url}`);
99+
----
100+
====
101+
102+
== User switching
103+
104+
User switching completely switches the user authenticating with the database for the given session, without the performance cost of instantiating an entire new driver instance.
105+
106+
An example of configuring user switching on a per request basis can be found in the example below. Note that the username and password are provided in HTTP headers `User` and `Password`, but this would not be recommended for production use:
107+
108+
.TypeScript
109+
[%collapsible]
110+
====
111+
[source, typescript, indent=0]
112+
----
113+
import { ApolloServer } from "@apollo/server";
114+
import { startStandaloneServer } from "@apollo/server/standalone";
115+
import { Neo4jGraphQL, Neo4jGraphQLContext } from "@neo4j/graphql";
116+
import neo4j from "neo4j-driver";
117+
118+
const typeDefs = `#graphql
119+
type Movie {
120+
title: String!
121+
}
122+
`;
123+
124+
const driver = neo4j.driver(
125+
"neo4j://localhost:7687",
126+
neo4j.auth.basic("neo4j", "password")
127+
);
128+
129+
const neo4jgraphql = new Neo4jGraphQL({
130+
typeDefs,
131+
driver,
132+
});
133+
134+
const schema = await neo4jgraphql.getSchema();
135+
136+
const server = new ApolloServer<Neo4jGraphQLContext>({
137+
schema,
138+
});
139+
140+
const { url } = await startStandaloneServer(server, {
141+
// Your async context function should async and return an object
142+
context: async ({ req }) => ({
143+
sessionConfig: {
144+
auth: neo4j.auth.basic(req.headers.user, req.headers.password),
145+
},
146+
}),
147+
});
148+
149+
console.log(`🚀 Server ready at: ${url}`);
150+
----
151+
====
152+
153+
.JavaScript
154+
[%collapsible]
155+
====
156+
[source, javascript, indent=0]
157+
----
158+
import { ApolloServer } from "@apollo/server";
159+
import { startStandaloneServer } from "@apollo/server/standalone";
160+
import { Neo4jGraphQL } from "@neo4j/graphql";
161+
import neo4j from "neo4j-driver";
162+
163+
const typeDefs = `#graphql
164+
type Movie {
165+
title: String!
166+
}
167+
`;
168+
169+
const driver = neo4j.driver(
170+
"neo4j://localhost:7687",
171+
neo4j.auth.basic("neo4j", "password")
172+
);
173+
174+
const neo4jgraphql = new Neo4jGraphQL({
175+
typeDefs,
176+
driver,
177+
});
178+
179+
const schema = await neo4jgraphql.getSchema();
180+
181+
const server = new ApolloServer({
182+
schema,
183+
});
184+
185+
const { url } = await startStandaloneServer(server, {
186+
// Your async context function should async and return an object
187+
context: async ({ req }) => ({
188+
sessionConfig: {
189+
auth: neo4j.auth.basic(req.headers.user, req.headers.password),
190+
},
191+
}),
192+
});
193+
194+
console.log(`🚀 Server ready at: ${url}`);
195+
----
196+
====
197+
198+

0 commit comments

Comments
 (0)