Open jirutka opened 1 year ago
In the preaccess phase, subrequests are not handled properly, so the verification process is not performed.
Can you please elaborate, how are they not handled properly? Also, this is something worth mentioning in the readme.
Related question, is it possible to somehow run auth_jwt before auth_request?
Can you please elaborate, how are they not handled properly? Also, this is something worth mentioning in the readme.
Annotated.
see: https://github.com/kjdev/nginx-auth-jwt/blob/main/README.md?plain=1#L228
Related question, is it possible to somehow run auth_jwt before auth_request?
When combined with auth_reqest it looks like this.
config:
# # auth_jwt_conf
# auth_jwt "" token=$session_jwt;
# error_page 401 = @oidc_error;
# auth_jwt_key_request /_jwks_uri;
# proxy_pass http://my_backend;
#OK: proxy_pass content
location = /auth/ok {
include auth_jwt_conf;
auth_request /auth_request/200;
auth_jwt_validate_alg RS256;
}
# NG: 403 error page
location = /auth/ng {
include auth_jwt_conf;
auth_request /auth_request/403;
auth_jwt_validate_alg RS256;
}
# NG: @oidc_error page
location = /auth/ok/invalid {
include auth_jwt_conf;
auth_request /auth_request/200;
auth_jwt_validate_alg ES256; # invalid auth_jwt
}
# NG: @oidc_error page
location = /auth/ng/invalid {
include auth_jwt_conf;
auth_request /auth_request/403;
auth_jwt_validate_alg ES256; # invalid auth_jwt
}
location = /auth_request/200 {
return 200 "OK";
}
location = /auth_request/403 {
return 403 "Forbidden";
}
see: https://github.com/kjdev/nginx-auth-jwt/blob/main/README.md?plain=1#L228
I see now, I didn’t understand what exactly it meant before. Why are nested in-memory subrequest a problem?
When combined with auth_reqest it looks like this.
The problem is with $jwt_
variables, they are not set when the auth_request
is executed. I’ve tried many workarounds (with njs), but nothing helped. What I want to achieve is to validate some claims with custom logic (role-based access control).
I'm not sure if it's possible without two steps since they are both access faces.
upstream auth_request_backend {
zone auth_request_backend 64k;
server 127.0.0.1:8889;
}
server {
listen 8889;
location / {
# valid auth_request
auth_request /test;
proxy_set_header username "$http_username";
proxy_pass http://my_backend;
}
location /test {
if ($http_username ~* "XXX") {
return 200;
}
return 403;
}
}
server {
location /auth/test {
# valid auth_jwt
auth_jwt_validate_alg RS256;
auth_jwt "" token=$session_jwt;
error_page 401 = @oidc_error;
auth_jwt_key_request /_jwks_uri;
proxy_set_header username $jwt_claim_sub;
proxy_pass http://auth_request_backend;
}
}
Can we do this by adjusting the execution phase and variable assignment process?
This workaround doesn’t look very good. :/
If auth_jwt_key_file
is used instead of auth_jwt_key_request
, then signature validation can be performed even in a subrequest, right?
It might be helpful if the module also accepts JWKS as a value (JSON encoded as a string), then I could more easily handle it myself from njs.
Aha, nginx (not this module) forbids nested subrequests, that’s the problem we face here. I found it in https://github.com/nginx/njs/issues/339#issuecomment-692293250. However, inside njs, I can use fetch
… except js_set
doesn’t support async functions (which fetch is).
What’s the reason for disabling signature verification in the ID token verification subrequest?
https://github.com/kjdev/nginx-auth-jwt/tree/main/example#changed-setting-for-id-token-verification