Skip to content

Commit 5f244f8

Browse files
committed
37: Removed auth_jwt_redirect and auth_jwt_loginurl directives
1 parent 0686f3a commit 5f244f8

File tree

4 files changed

+47
-161
lines changed

4 files changed

+47
-161
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ngx_http_auth_jwt_module.so

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,23 @@ This module requires several new nginx.conf directives, which can be specified i
1111

1212
```
1313
auth_jwt_key "00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF";
14-
auth_jwt_loginurl "https://yourdomain.com/loginpage";
1514
auth_jwt_enabled on;
1615
auth_jwt_algorithm HS256; # or RS256
1716
auth_jwt_validate_email on; # or off
1817
```
1918

20-
So, a typical use would be to specify the key and loginurl on the main level and then only turn on the locations that you want to secure (not the login page). Unauthorized requests are given 302 "Moved Temporarily" responses with a ___location of the specified loginurl.
19+
So, a typical use would be to specify the key on the main level and then only turn on the locations that you want to secure (not the login page). Unauthorized requests are given 401 "Unauthorized" responses, you can redirect them with the nginx's `error_page` directive.
2120

2221
```
23-
auth_jwt_redirect off;
22+
___location @login_redirect {
23+
allow all;
24+
return 302 https://yourdomain.com/loginpage;
25+
}
26+
27+
___location /secure-___location/ {
28+
auth_jwt_enabled on;
29+
error_page 401 = @login_redirect;
30+
}
2431
```
2532
If you prefer to return 401 Unauthorized, you may turn `auth_jwt_redirect` off.
2633

resources/test-jwt-nginx.conf

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
11
server {
22
auth_jwt_key "00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF";
3-
auth_jwt_loginurl "https://teslagov.com";
3+
set $auth_jwt_login_url "https://teslagov.com";
44
auth_jwt_enabled off;
5-
auth_jwt_redirect on;
65

76
listen 8000;
87
server_name localhost;
98

9+
root /usr/share/nginx/html;
10+
index index.html index.htm;
11+
12+
___location @login_redirect {
13+
return 302 $auth_jwt_login_url?redirect=$request_uri&$args;
14+
}
15+
1016
___location ~ ^/secure-no-redirect/ {
17+
rewrite "" / break;
1118
auth_jwt_enabled on;
12-
auth_jwt_redirect off;
13-
root /usr/share/nginx;
14-
index index.html index.htm;
1519
}
1620

1721
___location ~ ^/secure/ {
22+
rewrite "" / break;
1823
auth_jwt_enabled on;
1924
auth_jwt_validation_type COOKIE=rampartjwt;
20-
root /usr/share/nginx;
21-
index index.html index.htm;
25+
error_page 401 = @login_redirect;
2226
}
2327

2428
___location ~ ^/secure-auth-header/ {
29+
rewrite "" / break;
2530
auth_jwt_enabled on;
26-
root /usr/share/nginx;
27-
index index.html index.htm;
31+
error_page 401 = @login_redirect;
2832
}
2933

3034
___location ~ ^/secure-rs256/ {
35+
rewrite "" / break;
3136
auth_jwt_enabled on;
3237
auth_jwt_validation_type COOKIE=rampartjwt;
3338
auth_jwt_algorithm RS256;
@@ -40,13 +45,7 @@ ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g
4045
K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t
4146
BwIDAQAB
4247
-----END PUBLIC KEY-----";
43-
root /usr/share/nginx;
44-
index index.html index.htm;
4548
}
4649

47-
___location / {
48-
root /usr/share/nginx/html;
49-
index index.html index.htm;
50-
}
50+
___location / {}
5151
}
52-

src/ngx_http_auth_jwt_module.c

Lines changed: 21 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@
1919
#include "ngx_http_auth_jwt_string.h"
2020

2121
typedef 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

3836
static 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

Comments
 (0)