@@ -23,6 +23,7 @@ static char * ngx_http_auth_jwt_merge_loc_conf(ngx_conf_t *cf, void *parent, voi
23
23
static int hex_char_to_binary ( char ch , char * ret );
24
24
static int hex_to_binary ( const char * str , u_char * buf , int len );
25
25
static char * ngx_str_t_to_char_ptr (ngx_pool_t * pool , ngx_str_t str );
26
+ static ngx_table_elt_t * search_headers_in (ngx_http_request_t * r , u_char * name , size_t len );
26
27
27
28
static ngx_command_t ngx_http_auth_jwt_commands [] = {
28
29
@@ -84,9 +85,12 @@ ngx_module_t ngx_http_auth_jwt_module = {
84
85
85
86
static ngx_int_t ngx_http_auth_jwt_handler (ngx_http_request_t * r )
86
87
{
87
- ngx_int_t n ;
88
+ static const int BEARER_LEN = 7 ; // strlen("Bearer ");
89
+
88
90
ngx_str_t jwtCookieName = ngx_string ("rampartjwt" );
89
91
ngx_str_t passportKeyCookieName = ngx_string ("PassportKey" );
92
+ ngx_str_t authorizationHeaderName = ngx_string ("Authorization" );
93
+ ngx_int_t n ;
90
94
ngx_str_t jwtCookieVal ;
91
95
char * jwtCookieValChrPtr ;
92
96
char * return_url ;
@@ -97,6 +101,7 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
97
101
jwt_alg_t alg ;
98
102
time_t exp ;
99
103
time_t now ;
104
+ ngx_table_elt_t * authorizationHeader ;
100
105
101
106
jwtcf = ngx_http_get_module_loc_conf (r , ngx_http_auth_jwt_module );
102
107
@@ -109,6 +114,7 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
109
114
// jwtcf->auth_jwt_key.data,
110
115
// jwtcf->auth_jwt_enabled);
111
116
117
+
112
118
// get the cookie
113
119
// TODO: the cookie name could be passed in dynamicallly
114
120
n = ngx_http_parse_multi_header_lines (& r -> headers_in .cookies , & jwtCookieName , & jwtCookieVal );
@@ -163,6 +169,25 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
163
169
goto redirect ;
164
170
}
165
171
172
+ // if an Authorization header exists, it must match the cookie
173
+ authorizationHeader = search_headers_in (r , authorizationHeaderName .data , authorizationHeaderName .len );
174
+ if (authorizationHeader != NULL )
175
+ {
176
+ // compare lengths first
177
+ if (authorizationHeader -> value .len != jwtCookieVal .len + BEARER_LEN )
178
+ {
179
+ ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "Authorization and Cookie do not match lengths" );
180
+ goto redirect ;
181
+ }
182
+
183
+ // compare content
184
+ if (0 != strncmp ((const char * )(authorizationHeader -> value .data + BEARER_LEN ), (const char * )jwtCookieVal .data , jwtCookieVal .len ))
185
+ {
186
+ ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "Authorization and Cookie do not match content" );
187
+ goto redirect ;
188
+ }
189
+ }
190
+
166
191
return NGX_OK ;
167
192
168
193
redirect :
@@ -361,4 +386,48 @@ static char* ngx_str_t_to_char_ptr(ngx_pool_t *pool, ngx_str_t str)
361
386
return char_ptr ;
362
387
}
363
388
389
+ static ngx_table_elt_t * search_headers_in (ngx_http_request_t * r , u_char * name , size_t len )
390
+ {
391
+ ngx_list_part_t * part ;
392
+ ngx_table_elt_t * h ;
393
+ ngx_uint_t i ;
394
+
395
+ // Get the first part of the list. There is usual only one part.
396
+ part = & r -> headers_in .headers .part ;
397
+ h = part -> elts ;
398
+
399
+ // Headers list array may consist of more than one part, so loop through all of it
400
+ for (i = 0 ; /* void */ ; i ++ )
401
+ {
402
+ if (i >= part -> nelts )
403
+ {
404
+ if (part -> next == NULL )
405
+ {
406
+ /* The last part, search is done. */
407
+ break ;
408
+ }
409
+
410
+ part = part -> next ;
411
+ h = part -> elts ;
412
+ i = 0 ;
413
+ }
414
+
415
+ //Just compare the lengths and then the names case insensitively.
416
+ if (len != h [i ].key .len || ngx_strcasecmp (name , h [i ].key .data ) != 0 )
417
+ {
418
+ /* This header doesn't match. */
419
+ continue ;
420
+ }
421
+
422
+ /*
423
+ * Ta-da, we got one!
424
+ * Note, we've stopped the search at the first matched header
425
+ * while more then one header may match.
426
+ */
427
+ return & h [i ];
428
+ }
429
+
430
+ /* No headers was found */
431
+ return NULL ;
432
+ }
364
433
0 commit comments