nginx - njs - ngx_http_auth_request_module 如何向用户 return 302?
nginx - njs - ngx_http_auth_request_module how to return 302 to user?
我正在使用 njs ngx_http_auth_request_module。
我有这样的js函数;
function introspectAccessToken(r) {
r.subrequest("/_oauth2_send_request",
function(reply) {
if (reply.status == 200) {
r.return(204); // Token is valid, return success code
} else {
// need 302 here
}
}
);
}
文档说“如果子请求 return 是 2xx 响应代码,则允许访问。如果它 return 是 401 或 403,则访问被拒绝并显示相应的错误代码。任何由子请求编辑的其他响应代码 return 被视为错误。” http://nginx.org/en/docs/http/ngx_http_auth_request_module.html
如果 subsequest 进入“else”块,我需要 return 302 给用户。
有什么办法可以实现吗?如果我设置 r.return(302),它会在浏览器中显示错误页面,如文档所述。
编辑:我的 nginx.conf
location /my-webclient {
auth_request /_oauth2_token_introspection;
root /usr/share/nginx/html;
rewrite ^ /hmb-profile-webclient/index.html break;
}
location = /_oauth2_token_introspection {
internal;
js_content introspectAccessToken;
}
location /_oauth2_send_request {
internal;
proxy_method POST;
proxy_set_body $cookie_jwt;
proxy_pass http://my-specific-url;
}
http://my-specific-url returns
- 200,如果 jwt cookie 有效
- 302(位置 return),如果 jwt cookie 无效
知道了 - 我认为您甚至不需要 njs
来执行此操作。如果您的令牌自省端点不是使用 NJS 构建的,并且它不验证令牌是否有效 json 但它是用其他语言实现的,则此 NGINX 配置将起作用。
#cache for auth_request responses
proxy_cache_path /var/cache/nginx/oauth keys_zone=token_responses:1m max_size=2m;
#Your Server
server {
listen 80;
location / {
#Redirect Unauthed Request to some other location...
error_page 401 =302 http://localhost:9000/login;
auth_request /_auth_request;
proxy_pass http://127.0.0.1:8080;
}
location /_auth_request {
internal;
proxy_pass http://127.0.0.1:8090;
###place caching responses here to be more effective;
proxy_cache token_responses; # Enable caching
proxy_cache_key $cookie_jwt; # Cache for each access token
proxy_cache_lock on; # Duplicate tokens must wait
proxy_cache_valid 200 10s; # How long to use each response
proxy_ignore_headers Cache-Control Expires Set-Cookie;
}
}
....
如果您想使用 NJS 构建更多逻辑,例如验证令牌结构,您的方法是使用带有 js_set.
的 NJS 的正确方法
js_include oauth2.js; # Location of JavaScript code
server {
listen 80;
location / {
error_page 401 403 =302 http://localhost:9000/login;
auth_request /_oauth2_token_introspection;
proxy_pass http://my_backend;
}
location = /_oauth2_token_introspection {
internal;
js_content introspectAccessToken;
}
njs函数
function introspectAccessToken(r) {
r.subrequest("/_oauth2_send_request",
function(reply) {
if (reply.status == 200) {
var response = JSON.parse(reply.responseBody);
if (response.active == true) {
r.return(204); // Token is valid, return success code
} else {
r.return(403); // Token is invalid, return forbidden code
}
} else {
r.return(401); // Unexpected response, return 'auth required'
}
}
);
}
error_page
指令同样有效。根据您的代码,我假设您已经阅读了这篇文章?
https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/
ICYMI 这是一个很棒的博客 post 关于这个用例。
我正在使用 njs ngx_http_auth_request_module。
我有这样的js函数;
function introspectAccessToken(r) {
r.subrequest("/_oauth2_send_request",
function(reply) {
if (reply.status == 200) {
r.return(204); // Token is valid, return success code
} else {
// need 302 here
}
}
);
}
文档说“如果子请求 return 是 2xx 响应代码,则允许访问。如果它 return 是 401 或 403,则访问被拒绝并显示相应的错误代码。任何由子请求编辑的其他响应代码 return 被视为错误。” http://nginx.org/en/docs/http/ngx_http_auth_request_module.html
如果 subsequest 进入“else”块,我需要 return 302 给用户。
有什么办法可以实现吗?如果我设置 r.return(302),它会在浏览器中显示错误页面,如文档所述。
编辑:我的 nginx.conf
location /my-webclient {
auth_request /_oauth2_token_introspection;
root /usr/share/nginx/html;
rewrite ^ /hmb-profile-webclient/index.html break;
}
location = /_oauth2_token_introspection {
internal;
js_content introspectAccessToken;
}
location /_oauth2_send_request {
internal;
proxy_method POST;
proxy_set_body $cookie_jwt;
proxy_pass http://my-specific-url;
}
http://my-specific-url returns
- 200,如果 jwt cookie 有效
- 302(位置 return),如果 jwt cookie 无效
知道了 - 我认为您甚至不需要 njs
来执行此操作。如果您的令牌自省端点不是使用 NJS 构建的,并且它不验证令牌是否有效 json 但它是用其他语言实现的,则此 NGINX 配置将起作用。
#cache for auth_request responses
proxy_cache_path /var/cache/nginx/oauth keys_zone=token_responses:1m max_size=2m;
#Your Server
server {
listen 80;
location / {
#Redirect Unauthed Request to some other location...
error_page 401 =302 http://localhost:9000/login;
auth_request /_auth_request;
proxy_pass http://127.0.0.1:8080;
}
location /_auth_request {
internal;
proxy_pass http://127.0.0.1:8090;
###place caching responses here to be more effective;
proxy_cache token_responses; # Enable caching
proxy_cache_key $cookie_jwt; # Cache for each access token
proxy_cache_lock on; # Duplicate tokens must wait
proxy_cache_valid 200 10s; # How long to use each response
proxy_ignore_headers Cache-Control Expires Set-Cookie;
}
}
....
如果您想使用 NJS 构建更多逻辑,例如验证令牌结构,您的方法是使用带有 js_set.
的 NJS 的正确方法js_include oauth2.js; # Location of JavaScript code
server {
listen 80;
location / {
error_page 401 403 =302 http://localhost:9000/login;
auth_request /_oauth2_token_introspection;
proxy_pass http://my_backend;
}
location = /_oauth2_token_introspection {
internal;
js_content introspectAccessToken;
}
njs函数
function introspectAccessToken(r) {
r.subrequest("/_oauth2_send_request",
function(reply) {
if (reply.status == 200) {
var response = JSON.parse(reply.responseBody);
if (response.active == true) {
r.return(204); // Token is valid, return success code
} else {
r.return(403); // Token is invalid, return forbidden code
}
} else {
r.return(401); // Unexpected response, return 'auth required'
}
}
);
}
error_page
指令同样有效。根据您的代码,我假设您已经阅读了这篇文章?
https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/
ICYMI 这是一个很棒的博客 post 关于这个用例。