diff --git a/README.md b/README.md index 8c34d5c..ba5c34e 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,13 @@ auth_jwt_redirect off; ``` ## JWT Locations -By default, the`Authorization` header is used to provide a JWT for validation. However, you may use the `auth_jwt_location` directive to specify the name of the header or cookie which provides the JWT: +By default, the`Authorization` header is used to provide a JWT for validation. However, you may use the `auth_jwt_location` directive to specify the name of the header, cookie or queryString which provides the JWT: +the Querystring name must be "token". ```nginx auth_jwt_location HEADER=auth-token; # get the JWT from the "auth-token" header auth_jwt_location COOKIE=auth-token; # get the JWT from the "auth-token" cookie +auth_jwt_location QUERYSTRING=token; # get the JWT from the "token" query string ``` ## `sub` Validation diff --git a/src/ngx_http_auth_jwt_module.c b/src/ngx_http_auth_jwt_module.c index ffc8964..89772ac 100644 --- a/src/ngx_http_auth_jwt_module.c +++ b/src/ngx_http_auth_jwt_module.c @@ -609,11 +609,42 @@ static ngx_int_t load_public_key(ngx_conf_t *cf, auth_jwt_conf_t *conf) } } +ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value) +{ + u_char *p, *last; + size_t name_len; + ngx_str_t args; + args = r->args; + if (args.len == 0) { + return NGX_DECLINED; + } + p = args.data; + last = p + args.len; + name_len = ngx_strlen(name); + while (p < last) { + if ((p = ngx_strlcasestrn(p, last, name, name_len - 1)) == NULL) { + return NGX_DECLINED; + } + if ((p == args.data || *(p - 1) == '&') && (p + name_len == last || *(p + name_len) == '=')) { + p += name_len; + value->data = p; + while (p < last && *p != '&') { + p++; + } + value->len = p - value->data; + return NGX_OK; + } + p += name_len; + } + return NGX_DECLINED; +} + static char *get_jwt(ngx_http_request_t *r, ngx_str_t jwt_location) { static const char *HEADER_PREFIX = "HEADER="; static const char *BEARER_PREFIX = "Bearer "; static const char *COOKIE_PREFIX = "COOKIE="; + static const char *QUERY_STRING_PREFIX = "QUERYSTRING="; char *jwtPtr = NULL; ngx_log_debug(NGX_LOG_DEBUG, r->connection->log, 0, "jwt_location.len %d", jwt_location.len); @@ -638,6 +669,17 @@ static char *get_jwt(ngx_http_request_t *r, ngx_str_t jwt_location) jwtPtr = ngx_str_t_to_char_ptr(r->pool, jwtHeaderVal->value); } } + else if (jwt_location.len > sizeof(QUERY_STRING_PREFIX) && ngx_strncmp(jwt_location.data, QUERY_STRING_PREFIX, sizeof(QUERY_STRING_PREFIX) - 1) == 0) + { + ngx_str_t jwtQueryStringVal; + ngx_str_t tokenKey = ngx_string("token"); + jwt_location.data += sizeof(QUERY_STRING_PREFIX) - 1; + jwt_location.len -= sizeof(QUERY_STRING_PREFIX) - 1; + if (ngx_http_arg(r, tokenKey.data, tokenKey.len, &jwtQueryStringVal) == NGX_OK) + { + jwtPtr = ngx_str_t_to_char_ptr(r->pool, jwtQueryStringVal); + } + } else if (jwt_location.len > sizeof(COOKIE_PREFIX) && ngx_strncmp(jwt_location.data, COOKIE_PREFIX, sizeof(COOKIE_PREFIX) - 1) == 0) { bool has_cookie = false;