19
19
#include "ngx_http_auth_jwt_string.h"
20
20
21
21
typedef struct {
22
- ngx_str_t auth_jwt_loginurl ;
23
22
ngx_str_t auth_jwt_key ;
24
23
ngx_flag_t auth_jwt_enabled ;
25
- ngx_flag_t auth_jwt_redirect ;
26
24
ngx_str_t auth_jwt_validation_type ;
27
25
ngx_str_t auth_jwt_algorithm ;
28
26
ngx_flag_t auth_jwt_validate_email ;
@@ -37,13 +35,6 @@ static char * getJwt(ngx_http_request_t *r, ngx_str_t auth_jwt_validation_type);
37
35
38
36
static ngx_command_t ngx_http_auth_jwt_commands [] = {
39
37
40
- { ngx_string ("auth_jwt_loginurl" ),
41
- NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
42
- ngx_conf_set_str_slot ,
43
- NGX_HTTP_LOC_CONF_OFFSET ,
44
- offsetof(ngx_http_auth_jwt_loc_conf_t , auth_jwt_loginurl ),
45
- NULL },
46
-
47
38
{ ngx_string ("auth_jwt_key" ),
48
39
NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
49
40
ngx_conf_set_str_slot ,
@@ -58,13 +49,6 @@ static ngx_command_t ngx_http_auth_jwt_commands[] = {
58
49
offsetof(ngx_http_auth_jwt_loc_conf_t , auth_jwt_enabled ),
59
50
NULL },
60
51
61
- { ngx_string ("auth_jwt_redirect" ),
62
- NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_FLAG ,
63
- ngx_conf_set_flag_slot ,
64
- NGX_HTTP_LOC_CONF_OFFSET ,
65
- offsetof(ngx_http_auth_jwt_loc_conf_t , auth_jwt_redirect ),
66
- NULL },
67
-
68
52
{ ngx_string ("auth_jwt_validation_type" ),
69
53
NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
70
54
ngx_conf_set_str_slot ,
@@ -126,7 +110,6 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
126
110
ngx_str_t useridHeaderName = ngx_string ("x-userid" );
127
111
ngx_str_t emailHeaderName = ngx_string ("x-email" );
128
112
char * jwtCookieValChrPtr ;
129
- char * return_url ;
130
113
ngx_http_auth_jwt_loc_conf_t * jwtcf ;
131
114
u_char * keyBinary ;
132
115
jwt_t * jwt = NULL ;
@@ -140,21 +123,21 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
140
123
time_t now ;
141
124
ngx_str_t auth_jwt_algorithm ;
142
125
int keylen ;
143
-
126
+
144
127
jwtcf = ngx_http_get_module_loc_conf (r , ngx_http_auth_jwt_module );
145
-
146
- if (!jwtcf -> auth_jwt_enabled )
128
+
129
+ if (!jwtcf -> auth_jwt_enabled )
147
130
{
148
131
return NGX_DECLINED ;
149
132
}
150
-
133
+
151
134
jwtCookieValChrPtr = getJwt (r , jwtcf -> auth_jwt_validation_type );
152
135
if (jwtCookieValChrPtr == NULL )
153
136
{
154
137
ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "failed to find a jwt" );
155
- goto redirect ;
138
+ return NGX_HTTP_UNAUTHORIZED ;
156
139
}
157
-
140
+
158
141
// convert key from hex to binary, if a symmetric key
159
142
160
143
auth_jwt_algorithm = jwtcf -> auth_jwt_algorithm ;
@@ -165,7 +148,7 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
165
148
if (0 != hex_to_binary ((char * )jwtcf -> auth_jwt_key .data , keyBinary , jwtcf -> auth_jwt_key .len ))
166
149
{
167
150
ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "failed to turn hex key into binary" );
168
- goto redirect ;
151
+ return NGX_HTTP_UNAUTHORIZED ;
169
152
}
170
153
}
171
154
else if ( auth_jwt_algorithm .len == sizeof ("RS256" ) - 1 && ngx_strncmp (auth_jwt_algorithm .data , "RS256" , sizeof ("RS256" ) - 1 ) == 0 )
@@ -177,32 +160,32 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
177
160
else
178
161
{
179
162
ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "unsupported algorithm" );
180
- goto redirect ;
163
+ return NGX_HTTP_UNAUTHORIZED ;
181
164
}
182
-
165
+
183
166
// validate the jwt
184
167
jwtParseReturnCode = jwt_decode (& jwt , jwtCookieValChrPtr , keyBinary , keylen );
185
168
if (jwtParseReturnCode != 0 )
186
169
{
187
170
ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "failed to parse jwt" );
188
- goto redirect ;
171
+ return NGX_HTTP_UNAUTHORIZED ;
189
172
}
190
-
173
+
191
174
// validate the algorithm
192
175
alg = jwt_get_alg (jwt );
193
176
if (alg != JWT_ALG_HS256 && alg != JWT_ALG_RS256 )
194
177
{
195
178
ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "invalid algorithm in jwt %d" , alg );
196
- goto redirect ;
179
+ return NGX_HTTP_UNAUTHORIZED ;
197
180
}
198
-
181
+
199
182
// validate the exp date of the JWT
200
183
exp = (time_t )jwt_get_grant_int (jwt , "exp" );
201
184
now = time (NULL );
202
185
if (exp < now )
203
186
{
204
187
ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "the jwt has expired" );
205
- goto redirect ;
188
+ return NGX_HTTP_UNAUTHORIZED ;
206
189
}
207
190
208
191
// extract the userid
@@ -234,103 +217,6 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
234
217
jwt_free (jwt );
235
218
236
219
return NGX_OK ;
237
-
238
- redirect :
239
-
240
- if (jwt )
241
- {
242
- jwt_free (jwt );
243
- }
244
-
245
- r -> headers_out .___location = ngx_list_push (& r -> headers_out .headers );
246
-
247
- if (r -> headers_out .___location == NULL )
248
- {
249
- ngx_http_finalize_request (r , NGX_HTTP_INTERNAL_SERVER_ERROR );
250
- }
251
-
252
- r -> headers_out .___location -> hash = 1 ;
253
- r -> headers_out .___location -> key .len = sizeof ("Location" ) - 1 ;
254
- r -> headers_out .___location -> key .data = (u_char * ) "Location" ;
255
-
256
- if (r -> method == NGX_HTTP_GET )
257
- {
258
- int loginlen ;
259
- char * scheme ;
260
- ngx_str_t server ;
261
- ngx_str_t uri_variable_name = ngx_string ("request_uri" );
262
- ngx_int_t uri_variable_hash ;
263
- ngx_http_variable_value_t * request_uri_var ;
264
- ngx_str_t uri ;
265
- ngx_str_t uri_escaped ;
266
- uintptr_t escaped_len ;
267
-
268
- loginlen = jwtcf -> auth_jwt_loginurl .len ;
269
-
270
- scheme = (r -> connection -> ssl ) ? "https" : "http" ;
271
- server = r -> headers_in .server ;
272
-
273
- // get the URI
274
- uri_variable_hash = ngx_hash_key (uri_variable_name .data , uri_variable_name .len );
275
- request_uri_var = ngx_http_get_variable (r , & uri_variable_name , uri_variable_hash );
276
-
277
- // get the URI
278
- if (request_uri_var && !request_uri_var -> not_found && request_uri_var -> valid )
279
- {
280
- // ideally we would like the uri with the querystring parameters
281
- uri .data = ngx_palloc (r -> pool , request_uri_var -> len );
282
- uri .len = request_uri_var -> len ;
283
- ngx_memcpy (uri .data , request_uri_var -> data , request_uri_var -> len );
284
-
285
- // ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "found uri with querystring %s", ngx_str_t_to_char_ptr(r->pool, uri));
286
- }
287
- else
288
- {
289
- // fallback to the querystring without params
290
- uri = r -> uri ;
291
-
292
- // ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "fallback to querystring without params");
293
- }
294
-
295
- // escape the URI
296
- escaped_len = 2 * ngx_escape_uri (NULL , uri .data , uri .len , NGX_ESCAPE_ARGS ) + uri .len ;
297
- uri_escaped .data = ngx_palloc (r -> pool , escaped_len );
298
- uri_escaped .len = escaped_len ;
299
- ngx_escape_uri (uri_escaped .data , uri .data , uri .len , NGX_ESCAPE_ARGS );
300
-
301
- r -> headers_out .___location -> value .len = loginlen + sizeof ("?return_url=" ) - 1 + strlen (scheme ) + sizeof ("://" ) - 1 + server .len + uri_escaped .len ;
302
- return_url = ngx_palloc (r -> pool , r -> headers_out .___location -> value .len );
303
- ngx_memcpy (return_url , jwtcf -> auth_jwt_loginurl .data , jwtcf -> auth_jwt_loginurl .len );
304
- int return_url_idx = jwtcf -> auth_jwt_loginurl .len ;
305
- ngx_memcpy (return_url + return_url_idx , "?return_url=" , sizeof ("?return_url=" ) - 1 );
306
- return_url_idx += sizeof ("?return_url=" ) - 1 ;
307
- ngx_memcpy (return_url + return_url_idx , scheme , strlen (scheme ));
308
- return_url_idx += strlen (scheme );
309
- ngx_memcpy (return_url + return_url_idx , "://" , sizeof ("://" ) - 1 );
310
- return_url_idx += sizeof ("://" ) - 1 ;
311
- ngx_memcpy (return_url + return_url_idx , server .data , server .len );
312
- return_url_idx += server .len ;
313
- ngx_memcpy (return_url + return_url_idx , uri_escaped .data , uri_escaped .len );
314
- return_url_idx += uri_escaped .len ;
315
- r -> headers_out .___location -> value .data = (u_char * )return_url ;
316
-
317
- // ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "return_url: %s", ngx_str_t_to_char_ptr(r->pool, r->headers_out.___location->value));
318
- }
319
- else
320
- {
321
- // for non-get requests, redirect to the login page without a return URL
322
- r -> headers_out .___location -> value .len = jwtcf -> auth_jwt_loginurl .len ;
323
- r -> headers_out .___location -> value .data = jwtcf -> auth_jwt_loginurl .data ;
324
- }
325
-
326
- if (jwtcf -> auth_jwt_redirect )
327
- {
328
- return NGX_HTTP_MOVED_TEMPORARILY ;
329
- }
330
- else
331
- {
332
- return NGX_HTTP_UNAUTHORIZED ;
333
- }
334
220
}
335
221
336
222
@@ -342,7 +228,7 @@ static ngx_int_t ngx_http_auth_jwt_init(ngx_conf_t *cf)
342
228
cmcf = ngx_http_conf_get_module_main_conf (cf , ngx_http_core_module );
343
229
344
230
h = ngx_array_push (& cmcf -> phases [NGX_HTTP_ACCESS_PHASE ].handlers );
345
- if (h == NULL )
231
+ if (h == NULL )
346
232
{
347
233
return NGX_ERROR ;
348
234
}
@@ -359,18 +245,17 @@ ngx_http_auth_jwt_create_loc_conf(ngx_conf_t *cf)
359
245
ngx_http_auth_jwt_loc_conf_t * conf ;
360
246
361
247
conf = ngx_pcalloc (cf -> pool , sizeof (ngx_http_auth_jwt_loc_conf_t ));
362
- if (conf == NULL )
248
+ if (conf == NULL )
363
249
{
364
250
return NULL ;
365
251
}
366
-
252
+
367
253
// set the flag to unset
368
254
conf -> auth_jwt_enabled = (ngx_flag_t ) - 1 ;
369
- conf -> auth_jwt_redirect = (ngx_flag_t ) - 1 ;
370
255
conf -> auth_jwt_validate_email = (ngx_flag_t ) - 1 ;
371
256
372
257
ngx_conf_log_error (NGX_LOG_DEBUG , cf , 0 , "Created Location Configuration" );
373
-
258
+
374
259
return conf ;
375
260
}
376
261
@@ -381,20 +266,14 @@ ngx_http_auth_jwt_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
381
266
ngx_http_auth_jwt_loc_conf_t * prev = parent ;
382
267
ngx_http_auth_jwt_loc_conf_t * conf = child ;
383
268
384
- ngx_conf_merge_str_value (conf -> auth_jwt_loginurl , prev -> auth_jwt_loginurl , "" );
385
269
ngx_conf_merge_str_value (conf -> auth_jwt_key , prev -> auth_jwt_key , "" );
386
270
ngx_conf_merge_str_value (conf -> auth_jwt_validation_type , prev -> auth_jwt_validation_type , "" );
387
271
ngx_conf_merge_str_value (conf -> auth_jwt_algorithm , prev -> auth_jwt_algorithm , "HS256" );
388
272
ngx_conf_merge_off_value (conf -> auth_jwt_validate_email , prev -> auth_jwt_validate_email , 1 );
389
-
390
- if (conf -> auth_jwt_enabled == ((ngx_flag_t ) - 1 ))
391
- {
392
- conf -> auth_jwt_enabled = (prev -> auth_jwt_enabled == ((ngx_flag_t ) - 1 )) ? 0 : prev -> auth_jwt_enabled ;
393
- }
394
273
395
- if (conf -> auth_jwt_redirect == ((ngx_flag_t ) - 1 ))
274
+ if (conf -> auth_jwt_enabled == ((ngx_flag_t ) - 1 ))
396
275
{
397
- conf -> auth_jwt_redirect = (prev -> auth_jwt_redirect == ((ngx_flag_t ) - 1 )) ? 0 : prev -> auth_jwt_redirect ;
276
+ conf -> auth_jwt_enabled = (prev -> auth_jwt_enabled == ((ngx_flag_t ) - 1 )) ? 0 : prev -> auth_jwt_enabled ;
398
277
}
399
278
400
279
return NGX_CONF_OK ;
@@ -435,7 +314,7 @@ static char * getJwt(ngx_http_request_t *r, ngx_str_t auth_jwt_validation_type)
435
314
// get the cookie
436
315
// TODO: the cookie name could be passed in dynamicallly
437
316
n = ngx_http_parse_multi_header_lines (& r -> headers_in .cookies , & auth_jwt_validation_type , & jwtCookieVal );
438
- if (n != NGX_DECLINED )
317
+ if (n != NGX_DECLINED )
439
318
{
440
319
jwtCookieValChrPtr = ngx_str_t_to_char_ptr (r -> pool , jwtCookieVal );
441
320
}
0 commit comments