gpt4 book ai didi

nginx - 有条件的 nginx auth_request

转载 作者:行者123 更新时间:2023-12-03 13:42:23 28 4
gpt4 key购买 nike

我想让我的 nginx 代理仅在客户端尚未经过身份验证时才执行身份验证子请求。有条件的部分是我卡住的地方。如何制作配置以使每个 session 只对客户端进行一次身份验证?

我能够成功地向 Apache 执行 auth_request 并拉回我想要传递给后端的 header ,但这会发生在每个请求上,而且成本很高。

在此处的示例中,我的目标是仅在“授权” header 丢失或为空或包含 token 的 cookie 时才执行 auth_request

# DEFAULT BACKEND
location / {

proxy_pass_request_body off;

if ($http_authorization ~* '')
{
rewrite ^(.*)$ /__login;
}

if ($user !~* "([aa-zZ]+)@example.com")
{

}

if ($http_cookie !~* "(auth_cookie=([aa-zZ]+)@example.com)")
{
add_header Set-Cookie "auth_cookie=$user;domain=.example.com;Max-Age=3000";

}

proxy_pass_header x-webauth-user;
proxy_pass_header Set-Cookie;
proxy_pass http://example.com:6762/;

}

位置/__login {
内部的;
    auth_request /auth;
auth_request_set $user $upstream_http_x_webauth_user;
set $xuser $user;

add_header Auth-User $user;
proxy_set_header User-Name $user;
proxy_set_header Authorization $http_authorization;

#proxy_pass_header x-webauth-user;
#proxy_pass_header Set-Cookie;

proxy_pass http://example:6762/;

access_log /etc/nginx/login_debug.log;
}


location = /auth{
internal;
proxy_pass http://example.com:81/;

proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
#proxy_pass_header Set-Cookie;
#proxy_pass_header x-webauth-user;
}

Auth-User header 在第一次之后的所有请求中都会丢失,并且 cookie 似乎永远不会被设置,除此之外,页面实际上似乎并没有在浏览器中呈现。我显然做错了什么,请有人帮我解决这个问题。

最佳答案

请查看 NJS (https://nginx.org/en/docs/njs/) 模块。这真的很简单,肯定可以做你想做的事。这是示例解决方案:
文件:/etc/nginx/conf.d/default.conf:

server {
listen 80;
server_name "SOME_SERVER";
# make an authentication subrequest for every request
auth_request /auth;

# create a new variable AuthToken and set its value to the res.SOMEVALUE from the later subrequest...
auth_request_set $AuthToken $sent_http_token;

# add new AuthToken to the request
proxy_set_header Authorization $AuthToken;

location / {
proxy_pass http://SOME_ENDPOINT;
}

location = /auth {
internal;

proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;

js_content auth.main;
}

location /get-new-token-location {
internal;

proxy_pass http://SOMEURL;
}
}
以及 nginx.conf 文件的示例来展示如何启用 NJS 模块:
...
pid /var/run/nginx.pid;

load_module /usr/lib/nginx/modules/ngx_http_js_module.so;

events {
use epoll;
worker_connections 10000;
}


http {
# import njs scripts
js_import auth from /path/to/the/auth.js;

include /etc/nginx/conf.d/default.conf;
}
最后,来自 auth.js 文件的主要功能:
export default {main}

function main(r) {
var token = "";
// search token in Authorization header
if (this.requestHeaderExists(r, 'Authorization')) {
var m = r.headersIn.Authorization.match(/Bearer\s+(.+)/);

if (m !== null && typeof m[1] !== 'undefined') {
token = m[1];
}
}

// search token in cookie
if (token.length == 0) {
... code here ...
}

// token was found, you can somehow validate it if you want
if (token.length > 0) {
.., make sure token is valid...
}
else { // there is no token, so ask for the new one
r.subrequest('/get-new-token-location, { method: 'GET' }, function(reply) {
var res = JSON.parse(reply.responseBody);
// add token to the response headers of this sub-request
r.headersOut['token'] = res.SOMEVALUE;
}
}
r.return(200);
return;
}
请把它当作一个例子。好吧,也许它看起来很复杂,但它真的很强大,而且你肯定可以在万维网上找到更多的例子。

关于nginx - 有条件的 nginx auth_request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40431767/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com