我有一个授权模块,每当向私有端点发出请求时就会调用该模块。
该模块从标头中解析令牌Authorization
,并且:
- 如果无效,则返回 401
- 如果有效,则返回 200
- 如果它有效但即将在 X 分钟内过期,它会生成一个新令牌并在
Authorization
标头中返回该令牌。
“profile” 是私有端点之一,它的配置如下:
location /profile {
auth_request /jwtverify;
auth_request_set $authorization $upstream_http_authorization;
proxy_set_header authorization $authorization;
proxy_pass http://private-profile:80;
}
jwtverify
配置如下:
location = /jwtverify {
internal;
proxy_pass http://auth-module:8080/auth/verify;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
auth_request_set $http_authorization $upstream_http_authorization;
}
现在,除了要求 3 之外,一切正常:如果 auth 模块设置了标Authorization
头,客户端就永远不会收到它。
流程应该是这样的:
- 客户端发出请求
auth-module
拦截请求,如果有效,代理会将其传递给私有服务- 发送响应时,
auth-module
应保留设置的标头并发送给客户端
我想我没有正确理解如何结合,,,auth_request_set
也可能它们不适合这种情况。proxy_set_header
auth_request_set
有没有办法在 NGINX 中实现这一点?
答案1
好的,我能够在headers_more
模块。
完整配置是:
location = /jwtverify {
internal;
proxy_pass http://auth-module:8080/auth/verify;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location /profile {
auth_request /jwtverify;
# this gets called right after auth_request returns.
# it reads http "authorization" header from upstream (= auth_request)
# and sets it to the variable $auth_header
# https://stackoverflow.com/a/31485557/1759845
auth_request_set $auth_header $upstream_http_authorization;
# this gets called right before sending response to client.
# it adds the previously set variable (= "authorization"
# header from auth_request) to the response
more_set_headers "Authorization: $auth_header";
proxy_pass http://private-profile:80;
}
答案2
这就是我不用自定义模块就能解决这个问题的方法:
location /auth {
internal;
proxy_pass http://localhost:3000/auth;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Remote-Addr $remote_addr;
proxy_set_header X-Original-Host $host;
}
location /protected {
auth_request /auth;
auth_request_set $authentication_id $sent_http_x_authentication_id;
proxy_pass http://localhost:3000/protected;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Remote-Addr $remote_addr;
proxy_set_header X-Original-Host $host;
proxy_set_header X-Authentication-Id: $authentication_id;
}
- 让您的
/auth
端点包含响应标头。我的设置X-Authentication-Id
- 用于
auth_request_set
根据响应头设置变量 - 使用变量将标头设置为
/protected
请求的一部分