diff --git a/scripts b/scripts index 7ce7024..63f5489 100755 --- a/scripts +++ b/scripts @@ -190,6 +190,7 @@ build_test() { --build-arg RUNNER_BASE_IMAGE=${runnerBaseImage} \ --build-arg PORT=${port} \ --build-arg SSL_PORT=${sslPort} \ + --build-arg platform="linux/amd64" \ ${dockerArgs} } @@ -217,34 +218,15 @@ test() { trap 'test_cleanup' 0 printf "${MAGENTA}Running tests...${NC}\n" + printf "\n" + printf "Executing tests with the following options:\n" + printf " SSL Version: ${SSL_VERSION}\n" + printf " LIBJWT Version: ${LIBJWT_VERSION}\n" + printf " NGINX Version: ${NGINX_VERSION}\n" + docker compose \ -p ${TEST_CONTAINER_NAME_PREFIX} \ - -f ${TEST_COMPOSE_FILE} up \ - --no-start - - test_now -} - -test_now() { - nginxContainerName="${TEST_CONTAINER_NAME_PREFIX}-nginx" - runnerContainerName="${TEST_CONTAINER_NAME_PREFIX}-runner" - - echo - echo "Executing tests with the following options:" - echo " SSL Version: ${SSL_VERSION}" - echo " LIBJWT Version: ${LIBJWT_VERSION}" - echo " NGINX Version: ${NGINX_VERSION}" - - docker start ${nginxContainerName} - - if [ "$(docker container inspect -f '{{.State.Running}}' ${nginxContainerName})" != "true" ]; then - printf "${RED}Failed to start container \"${nginxContainerName}\". See logs below:\n" - docker logs ${nginxContainerName} - printf "${NC}\n" - return 1 - fi - - docker start -a ${runnerContainerName} + -f ${TEST_COMPOSE_FILE} up } test_cleanup() { @@ -258,9 +240,16 @@ get_port() { endPort=$((startPort + 100)) for p in $(seq ${startPort} ${endPort}); do - if ! ss -ln | grep -q ":${p} "; then - echo ${p} - break + if [ "$(uname)" == "Darwin" ]; then + if ! lsof -i -P | grep LISTEN | grep -q ":${p} "; then + echo ${p} + break + fi + elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then + if ! ss -ln | grep -q ":${p} "; then + echo ${p} + break + fi fi done } diff --git a/src/ngx_http_auth_jwt_module.c b/src/ngx_http_auth_jwt_module.c index 59b84ac..9f29d7f 100644 --- a/src/ngx_http_auth_jwt_module.c +++ b/src/ngx_http_auth_jwt_module.c @@ -350,9 +350,11 @@ static char *merge_extract_var_claims(ngx_conf_t *cf, ngx_command_t *cmd, void * static ngx_int_t get_jwt_var_claim(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "getting jwt value for var index %l", *((ngx_uint_t *)data)); + ngx_uint_t *claim_idx = (ngx_uint_t *)data; auth_jwt_ctx_t *ctx = get_request_jwt_ctx(r); + ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "getting jwt var claim for var at index %l", *claim_idx); + if (ctx == NULL) { ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "no module context found while getting jwt value"); @@ -361,7 +363,6 @@ static ngx_int_t get_jwt_var_claim(ngx_http_request_t *r, ngx_http_variable_valu } else { - ngx_uint_t *claim_idx = (ngx_uint_t *)data; ngx_str_t claim_value = ((ngx_str_t *)ctx->claim_values->elts)[*claim_idx]; v->valid = 1; diff --git a/test/docker-compose-test.yml b/test/docker-compose-test.yml index cc570c5..bcb7b5b 100644 --- a/test/docker-compose-test.yml +++ b/test/docker-compose-test.yml @@ -10,8 +10,14 @@ services: args: BASE_IMAGE: ${FULL_IMAGE_NAME}:${NGINX_VERSION:?required} platform: linux/amd64 + pull_policy: always logging: driver: ${LOG_DRIVER:-journald} + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/ping"] + interval: 30s + timeout: 5s + retries: 3 runner: container_name: ${TEST_CONTAINER_NAME_PREFIX:?required}-runner @@ -21,5 +27,7 @@ services: platforms: - linux/amd64 platform: linux/amd64 + pull_policy: always depends_on: - - nginx + nginx: + condition: service_healthy diff --git a/test/ec_key_256.pem b/test/ec_key_256.pem deleted file mode 100644 index 4206969..0000000 --- a/test/ec_key_256.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgOlEBGcZxxhv8FkN0 -YIvax6fnhJbMeotzIEBxIglkNu6hRANCAATP1NpDzvZmKd2Mw6hIrv4nzUfNu7OK -mT5VuL5LhvUgzTqVGuxwevA7DlFsNVSfCljIBG3geio3fcd4k0Z9SygL ------END PRIVATE KEY----- diff --git a/test/ec_key_384.pem b/test/ec_key_384.pem deleted file mode 100644 index 2aa5780..0000000 --- a/test/ec_key_384.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDADyrL6llSQoQOZ/PF/ -l761kAbrTwn4vu30Kr34ScW6bRKVXLq3cT3QssJ1nF9B63qhZANiAAQ48dOfIEd3 -0TCVE0JT4ZU0Db7Ftz+ex7lojP7uqTY9OI59yoMB01zUN4JK30BRXS9Yv0A9Bu1z -fgLu93FSn0kd0zIPMvuu5LUt60M/miSt2lA0OrqFhKjx6FFdN/lNh64= ------END PRIVATE KEY----- diff --git a/test/ec_key_521.pem b/test/ec_key_521.pem deleted file mode 100644 index 10471dc..0000000 --- a/test/ec_key_521.pem +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAKkag6aVn4XAbaALo -0b3pypdP5RBX7uKxHmKlkNCcpA0oVTdgjnM5NpJP8ZOM6NjVhEzsn6c/Tdn8hL8w -SI55hFWhgYkDgYYABABpTipSvbs8fq44u4fA+v7DTNYViA58sqbrxjxdzwWZ8eEj -CXsH7yzSGx3Y19NSyrX8HbjWmrj5uxiKeFCB8mGzTwDcFIKCMeMkHjZs/fmVOumR -a2XSpj7BP6wqcN6Pf+UqECivGAZGRHoabo/dm5zF9M3gO+G9eOrf3G1wgFFM7Vzb -Ow== ------END PRIVATE KEY----- diff --git a/test/etc/nginx/conf.d/test.conf b/test/etc/nginx/conf.d/test.conf index 4e5d764..7348a5e 100644 --- a/test/etc/nginx/conf.d/test.conf +++ b/test/etc/nginx/conf.d/test.conf @@ -1,6 +1,8 @@ error_log /var/log/nginx/debug.log debug; access_log /var/log/nginx/access.log; +log_format extractTest 'Log extract test sub: $jwt_claim_sub'; + server { listen %{PORT}; listen %{SSL_PORT} ssl; @@ -15,6 +17,10 @@ server { auth_jwt_loginurl "https://example.com/login"; auth_jwt_enabled off; + location /ping { + return 200 "pong"; + } + location / { alias /usr/share/nginx/html/; try_files index.html =404; @@ -445,4 +451,16 @@ vXjq39xtcIBRTO1c2zs= auth_jwt_enabled on; auth_jwt_redirect on; } + + location /log { + auth_jwt_enabled on; + auth_jwt_redirect off; + auth_jwt_location HEADER=Authorization; + auth_jwt_validate_sub on; + auth_jwt_extract_var_claims sub; + + access_log /var/log/nginx/test_access.log extractTest; + + return 200 "logged sub"; + } } diff --git a/test/rsa_key_2048.pem b/test/rsa_key_2048.pem deleted file mode 100755 index 0f58120..0000000 --- a/test/rsa_key_2048.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDC2kwAziXUf33m -iqWp0yG6o259+nj7hpQLC4UT0Hmz0wmvreDJ/yNbSgOvsxvVdvzL2IaRZ+Gi5mo0 -lswWvL6IGz7PZO0kXTq9sdBnNqMOx27HddV9e/2/p0MgibJTbgywY2Sk23QYhJpq -Kq/nU0xlBfSaI5ddZ2RC9ZNkVeGawUKYksTruhAVJqviHN8BoK6VowP5vcxyyOWH -TK9KruDqzCIhqwRTeo0spokBkTN/LCuhVivcHAzUiJVtB4qAiTI9L/zkzhjpKz9P -45aLU54rj011gG8U/6E1USh5nMnPkr+d3oLfkhfS3Zs3kJVdyFQWZpQxiTaI92Fd -2wLvbS0HAgMBAAECggEAD8dTnkETSSjlzhRuI9loAtAXM3Zj86JLPLW7GgaoxEoT -n7lJ2bGicFMHB2ROnbOb9vnas82gtOtJsGaBslmoaCckp/C5T1eJWTEb+i+vdpPp -wZcmKZovyyRFSE4+NYlU17fEv6DRvuaGBpDcW7QgHJIl45F8QWEM+msee2KE+V4G -z/9vAQ+sOlvsb4mJP1tJIBx9Lb5loVREwCRy2Ha9tnWdDNar8EYkOn8si4snPT+E -3ZCy8mlcZyUkZeiS/HdtydxZfoiwrSRYamd1diQpPhWCeRteQ802a7ds0Y2YzgfF -UaYjNuRQm7zA//hwbXS7ELPyNMU15N00bajlG0tUOQKBgQDnLy01l20OneW6A2cI -DIDyYhy5O7uulsaEtJReUlcjEDMkin8b767q2VZHb//3ZH+ipnRYByUUyYUhdOs2 -DYRGGeAebnH8wpTT4FCYxUsIUpDfB7RwfdBONgaKewTJz/FPswy1Ye0b5H2c6vVi -m2FZ33HQcoZ3wvFFqyGVnMzpOwKBgQDXxL95yoxUGKa8vMzcE3Cn01szh0dFq0sq -cFpM+HWLVr84CItuG9H6L0KaStEEIOiJsxOVpcXfFFhsJvOGhMA4DQTwH4WuXmXp -1PoVMDlV65PYqvhzwL4+QhvZO2bsrEunITXOmU7CI6kilnAN3LuP4HbqZgoX9lqP -I31VYzLupQKBgGEYck9w0s/xxxtR9ILv5XRnepLdoJzaHHR991aKFKjYU/KD7JDK -INfoAhGs23+HCQhCCtkx3wQVA0Ii/erM0II0ueluD5fODX3TV2ZibnoHW2sgrEsW -vFcs36BnvIIaQMptc+f2QgSV+Z/fGsKYadG6Q+39O7au/HB7SHayzWkjAoGBAMgt -Fzslp9TpXd9iBWjzfCOnGUiP65Z+GWkQ/SXFqD+SRir0+m43zzGdoNvGJ23+Hd6K -TdQbDJ0uoe4MoQeepzoZEgi4JeykVUZ/uVfo+nh06yArVf8FxTm7WVzLGGzgV/uA -+wtl/cRtEyAsk1649yW/KHPEIP8kJdYAJeoO8xSlAoGAERMrkFR7KGYZG1eFNRdV -mJMq+Ibxyw8ks/CbiI+n3yUyk1U8962ol2Q0T4qjBmb26L5rrhNQhneM4e8mo9FX -LlQapYkPvkdrqW0Bp72A/UNAvcGTmN7z5OCJGMUutx2hmEAlrYmpLKS8pM/p9zpK -tEOtzsP5GMDYVlEp1jYSjzQ= ------END PRIVATE KEY----- diff --git a/test/test.sh b/test/test.sh index c726a75..9a8cb72 100755 --- a/test/test.sh +++ b/test/test.sh @@ -27,9 +27,10 @@ run_test () { local curlCommand= local exitCode= local response= + local expectedLogSub= local testNum="${GRAY}${NUM_TESTS}${NC}\t" - while getopts "n:asp:r:c:x:" option; do + while getopts "n:asp:r:c:x:l:" option; do case $option in n) name=$OPTARG;; @@ -44,6 +45,8 @@ run_test () { expectedResponseRegex=$OPTARG;; x) extraCurlOpts=$OPTARG;; + l) + expectedLogSub=$OPTARG;; \?) # Invalid option printf "Error: Invalid option\n"; exit;; @@ -81,6 +84,16 @@ run_test () { if [ "${okay}" == '1' ]; then printf "${GREEN}${name}"; fi + + if ["${expectedLogSub}" != ""]; then + local logEntry=$(tail -n 1 /var/log/nginx/test_access.log) + + if ["${logEntry}" != "Log extract test sub:${expectedLogSub}"]; then + printf "${RED}${name} -- log extracted sub is not what is expected:${expectedLogSub}; logged: ${logEntry}" + NUM_FAILED=$((${NUM_FAILED} + 1)) + okay=0 + fi + fi fi if [ "${DEBUG}" == "${NUM_TESTS}" ]; then @@ -332,13 +345,18 @@ main() { -c 401 \ -x '--header "Authorization: Bearer ${JWT_HS256_MISSING_SUB}"' - run_test -n 'extracts single claim to response body' \ + run_test -n 'extracts single claim as var' \ -p '/secure/extract-claim/body/sub' \ -c 200 \ -r 'sub: some-long-uuid$' \ -x '--header "Authorization: Bearer ${JWT_HS256_VALID}"' - run_test -n 'extracts multiple claims to response body' \ + run_test -n 'fails gracefully when extracting single claim as var with no JWT' \ + -p '/secure/extract-claim/body/sub' \ + -c 200 \ + -r 'sub: some-long-uuid$' + + run_test -n 'extracts multiple claims as vars' \ -p '/secure/extract-claim/body/multiple' \ -c 200 \ -r 'you are: hello world$' \ @@ -369,6 +387,13 @@ main() { run_test -n 'return_url includes query when redirected to login' \ -p '/return-url?test=123' \ -r '< Location: https://example\.com/login\?return_url=http://nginx.*/return-url%3Ftest=123' + + run_test -n 'acess_log extract valid sub' \ + -p '/log' \ + -c 200 \ + -r 'logged sub' \ + -x '--header "Authorization: Bearer ${JWT_HS256_VALID}"' \ + -l 'some-long-uuid' if [[ "${NUM_FAILED}" = '0' ]]; then printf "\nRan ${NUM_TESTS} tests successfully (skipped ${NUM_SKIPPED}).\n"