You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Configures the JWT authentication and authorization filters to include an additional JWT claim which is either nested or using special characters not supported by GraphQL.
Copy file name to clipboardExpand all lines: modules/ROOT/pages/security/configuration.adoc
+89-60Lines changed: 89 additions & 60 deletions
Original file line number
Diff line number
Diff line change
@@ -1,16 +1,28 @@
1
1
= Configuration
2
2
:description: This page describes how to configure authentication and authorization features in the Neo4j GraphQL Library.
3
3
4
+
The Neo4j GraphQL Library uses JSON Web Token (JWT) authentication.
5
+
JWTs are tokens containing claims or statements about the user or client making the request.
6
+
These claims can include information such as the user's ID or roles.
7
+
8
+
When a user or client logs in to the API, the API generates a JWT and returns it to the client.
9
+
The client then includes the JWT with each subsequent request to the API.
10
+
The API verifies the JWT and returns the requested data if the JWT is valid.
11
+
12
+
// ^ is this paragraph accurate?
13
+
4
14
== Instantiation
5
15
6
-
The Neo4j GraphQL Library can accept JSON Web Tokens via two mechanisms:
16
+
The Neo4j GraphQL Library can accept two types of JWTs:
7
17
8
18
* Encoded JWTs in the `token` field of the request context.
9
19
* Decoded JWTs in the `jwt` field of the request context.
10
20
11
-
If using the former, the library will need to be configured with a key to decode and verify the token.
21
+
=== Encoded JWTs
12
22
13
-
The following code block demonstrates using Apollo Server, extracting the `Authorization` header from the request, and putting it into the appropriate context field:
23
+
To use encoded JWTs, the library must to be configured with a key to decode and verify the tokens.
24
+
25
+
The following code block uses Apollo Server, extracts the `Authorization` header from the request and puts it in the appropriate context field:
Optionally, if a custom decoding mechanism is required, that same header can be decoded and the resulting JWT payload put into the `jwt` field of the context.
30
42
31
-
=== Symmetric secret
43
+
// ^ Can we show the above in a code listing?
44
+
45
+
==== Symmetric secret
32
46
33
47
To configure the library with a symmetric secret (e.g. "secret"), the following instantiation is required:
34
48
49
+
// ^ What is a symmetric secret? What is its purpose?
50
+
35
51
[source, typescript, indent=0]
36
52
----
37
53
new Neo4jGraphQL({
@@ -44,9 +60,11 @@ new Neo4jGraphQL({
44
60
});
45
61
----
46
62
47
-
=== JWKS endpoint
63
+
==== JWKS endpoint
48
64
49
-
To configure the library to verify tokens against a JWKS endpoint, "https://www.myapplication.com/.well-known/jwks.json", the following instantiation is required:
65
+
To configure the library to verify tokens against a JWKS endpoint, for example "https://www.myapplication.com/.well-known/jwks.json", the following instantiation is required:
66
+
67
+
// ^ What is the purpose?
50
68
51
69
[source, typescript, indent=0]
52
70
----
@@ -62,14 +80,66 @@ new Neo4jGraphQL({
62
80
});
63
81
----
64
82
65
-
[[authentication-and-authorization-jwt]]
66
-
== JWT
83
+
==== Passing in encoded JWTs
84
+
85
+
// This was at the end of the file, I thought it could be moved here instead. What about decoded JWTs?
86
+
87
+
To pass in an encoded JWT, use the token field of the context.
88
+
When using Apollo Server, extract the authorization header into the token property of the context:
Alternatively, you can pass a key `jwt` of type `JwtPayload` into the context, which has the following definition:
111
+
112
+
[source, typescript, indent=0]
113
+
----
114
+
// standard claims https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
115
+
interface JwtPayload {
116
+
[key: string]: any;
117
+
iss?: string | undefined;
118
+
sub?: string | undefined;
119
+
aud?: string | string[] | undefined;
120
+
exp?: number | undefined;
121
+
nbf?: number | undefined;
122
+
iat?: number | undefined;
123
+
jti?: string | undefined;
124
+
}
125
+
----
126
+
127
+
[WARNING]
128
+
Do not pass in the header or the signature.
129
+
130
+
=== Decoded JWTs
131
+
132
+
// What could be added here?
133
+
134
+
== Adding JWT claims
67
135
68
136
By default, filtering is available on https://www.rfc-editor.org/rfc/rfc7519#section-4.1[the registered claim names] in the JWT specification.
69
137
70
138
Filtering can be configured for additional JWT claims using the `@jwt` directive and, in some circumstances, the `@jwtClaim` directive.
71
139
72
-
If you configure an additional `roles` claim, which is an array of strings located at the root of the JWT payload, the following must be added to the type definitions:
140
+
=== The `@jwt` directive
141
+
142
+
If you configure an additional `roles` claim, which is an array of strings located at the root of the JWT payload, add the following to the type definitions:
73
143
74
144
[source, graphql, indent=0]
75
145
----
@@ -78,11 +148,12 @@ type JWT @jwt {
78
148
}
79
149
----
80
150
81
-
Note that the type name here, `JWT`, is not required, and this can have any name as long as it is decorated with the `@jwt` directive.
151
+
Note that the type name `JWT` is not required.
152
+
You can use any name as long as it is decorated with the `@jwt` directive.
82
153
83
-
=== Nested claims
154
+
=== The `@jwtClaim` directive
84
155
85
-
If the previous `roles` claim is not located at the JWT payload root, but instead in a nested location, for example:
156
+
A `roles` claim is not necessarily located at the JWT payload root, but can instead be in a nested location, for example:
86
157
87
158
[source, json, indent=0]
88
159
----
@@ -94,7 +165,9 @@ If the previous `roles` claim is not located at the JWT payload root, but instea
94
165
}
95
166
----
96
167
97
-
This needs to be configured using the `@jwtClaim` directive:
168
+
// ^ why is this a nested location? can we show the nesting?
169
+
170
+
In this case, use the `@jwtClaim` directive:
98
171
99
172
[source, graphql, indent=0]
100
173
----
@@ -103,7 +176,7 @@ type JWT @jwt {
103
176
}
104
177
----
105
178
106
-
Additionally, if this nested location contains any `.` characters in the path, for example:
179
+
Additionally, the nested location may contain `.` characters in the path, for example:
107
180
108
181
[source, json, indent=0]
109
182
----
@@ -115,7 +188,7 @@ Additionally, if this nested location contains any `.` characters in the path, f
115
188
}
116
189
----
117
190
118
-
These characters need to be escaped:
191
+
Escape these characters:
119
192
120
193
[source, graphql, indent=0]
121
194
----
@@ -126,50 +199,6 @@ type JWT @jwt {
126
199
127
200
[NOTE]
128
201
====
129
-
The seemingly excessive escaping is required to doubly escape: once for GraphQL and once for `dot-prop`, which is used under the hood to resolve the path.
202
+
This way of escaping is necessary to escape twice: once for GraphQL and once for `dot-prop`, which is used under the hood to resolve the path.
130
203
====
131
204
132
-
== Passing in JWTs
133
-
134
-
To pass in an encoded JWT, you must use the token field of the context.
135
-
When using Apollo Server, extract the authorization header into the token property of the context as follows:
0 commit comments