1919#include "ngx_http_auth_jwt_string.h"
2020
2121typedef struct {
22- ngx_str_t auth_jwt_loginurl ;
2322 ngx_str_t auth_jwt_key ;
2423 ngx_flag_t auth_jwt_enabled ;
25- ngx_flag_t auth_jwt_redirect ;
2624 ngx_str_t auth_jwt_validation_type ;
2725 ngx_str_t auth_jwt_algorithm ;
2826 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);
3735
3836static ngx_command_t ngx_http_auth_jwt_commands [] = {
3937
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-
4738 { ngx_string ("auth_jwt_key" ),
4839 NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
4940 ngx_conf_set_str_slot ,
@@ -58,13 +49,6 @@ static ngx_command_t ngx_http_auth_jwt_commands[] = {
5849 offsetof(ngx_http_auth_jwt_loc_conf_t , auth_jwt_enabled ),
5950 NULL },
6051
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-
6852 { ngx_string ("auth_jwt_validation_type" ),
6953 NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
7054 ngx_conf_set_str_slot ,
@@ -126,7 +110,6 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
126110 ngx_str_t useridHeaderName = ngx_string ("x-userid" );
127111 ngx_str_t emailHeaderName = ngx_string ("x-email" );
128112 char * jwtCookieValChrPtr ;
129- char * return_url ;
130113 ngx_http_auth_jwt_loc_conf_t * jwtcf ;
131114 u_char * keyBinary ;
132115 jwt_t * jwt = NULL ;
@@ -140,21 +123,21 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
140123 time_t now ;
141124 ngx_str_t auth_jwt_algorithm ;
142125 int keylen ;
143-
126+
144127 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 )
147130 {
148131 return NGX_DECLINED ;
149132 }
150-
133+
151134 jwtCookieValChrPtr = getJwt (r , jwtcf -> auth_jwt_validation_type );
152135 if (jwtCookieValChrPtr == NULL )
153136 {
154137 ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "failed to find a jwt" );
155- goto redirect ;
138+ return NGX_HTTP_UNAUTHORIZED ;
156139 }
157-
140+
158141 // convert key from hex to binary, if a symmetric key
159142
160143 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)
165148 if (0 != hex_to_binary ((char * )jwtcf -> auth_jwt_key .data , keyBinary , jwtcf -> auth_jwt_key .len ))
166149 {
167150 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 ;
169152 }
170153 }
171154 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)
177160 else
178161 {
179162 ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "unsupported algorithm" );
180- goto redirect ;
163+ return NGX_HTTP_UNAUTHORIZED ;
181164 }
182-
165+
183166 // validate the jwt
184167 jwtParseReturnCode = jwt_decode (& jwt , jwtCookieValChrPtr , keyBinary , keylen );
185168 if (jwtParseReturnCode != 0 )
186169 {
187170 ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "failed to parse jwt" );
188- goto redirect ;
171+ return NGX_HTTP_UNAUTHORIZED ;
189172 }
190-
173+
191174 // validate the algorithm
192175 alg = jwt_get_alg (jwt );
193176 if (alg != JWT_ALG_HS256 && alg != JWT_ALG_RS256 )
194177 {
195178 ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "invalid algorithm in jwt %d" , alg );
196- goto redirect ;
179+ return NGX_HTTP_UNAUTHORIZED ;
197180 }
198-
181+
199182 // validate the exp date of the JWT
200183 exp = (time_t )jwt_get_grant_int (jwt , "exp" );
201184 now = time (NULL );
202185 if (exp < now )
203186 {
204187 ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 , "the jwt has expired" );
205- goto redirect ;
188+ return NGX_HTTP_UNAUTHORIZED ;
206189 }
207190
208191 // extract the userid
@@ -234,103 +217,6 @@ static ngx_int_t ngx_http_auth_jwt_handler(ngx_http_request_t *r)
234217 jwt_free (jwt );
235218
236219 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- }
334220}
335221
336222
@@ -342,7 +228,7 @@ static ngx_int_t ngx_http_auth_jwt_init(ngx_conf_t *cf)
342228 cmcf = ngx_http_conf_get_module_main_conf (cf , ngx_http_core_module );
343229
344230 h = ngx_array_push (& cmcf -> phases [NGX_HTTP_ACCESS_PHASE ].handlers );
345- if (h == NULL )
231+ if (h == NULL )
346232 {
347233 return NGX_ERROR ;
348234 }
@@ -359,18 +245,17 @@ ngx_http_auth_jwt_create_loc_conf(ngx_conf_t *cf)
359245 ngx_http_auth_jwt_loc_conf_t * conf ;
360246
361247 conf = ngx_pcalloc (cf -> pool , sizeof (ngx_http_auth_jwt_loc_conf_t ));
362- if (conf == NULL )
248+ if (conf == NULL )
363249 {
364250 return NULL ;
365251 }
366-
252+
367253 // set the flag to unset
368254 conf -> auth_jwt_enabled = (ngx_flag_t ) - 1 ;
369- conf -> auth_jwt_redirect = (ngx_flag_t ) - 1 ;
370255 conf -> auth_jwt_validate_email = (ngx_flag_t ) - 1 ;
371256
372257 ngx_conf_log_error (NGX_LOG_DEBUG , cf , 0 , "Created Location Configuration" );
373-
258+
374259 return conf ;
375260}
376261
@@ -381,20 +266,14 @@ ngx_http_auth_jwt_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
381266 ngx_http_auth_jwt_loc_conf_t * prev = parent ;
382267 ngx_http_auth_jwt_loc_conf_t * conf = child ;
383268
384- ngx_conf_merge_str_value (conf -> auth_jwt_loginurl , prev -> auth_jwt_loginurl , "" );
385269 ngx_conf_merge_str_value (conf -> auth_jwt_key , prev -> auth_jwt_key , "" );
386270 ngx_conf_merge_str_value (conf -> auth_jwt_validation_type , prev -> auth_jwt_validation_type , "" );
387271 ngx_conf_merge_str_value (conf -> auth_jwt_algorithm , prev -> auth_jwt_algorithm , "HS256" );
388272 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- }
394273
395- if (conf -> auth_jwt_redirect == ((ngx_flag_t ) - 1 ))
274+ if (conf -> auth_jwt_enabled == ((ngx_flag_t ) - 1 ))
396275 {
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 ;
398277 }
399278
400279 return NGX_CONF_OK ;
@@ -435,7 +314,7 @@ static char * getJwt(ngx_http_request_t *r, ngx_str_t auth_jwt_validation_type)
435314 // get the cookie
436315 // TODO: the cookie name could be passed in dynamicallly
437316 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 )
439318 {
440319 jwtCookieValChrPtr = ngx_str_t_to_char_ptr (r -> pool , jwtCookieVal );
441320 }
0 commit comments