【发布时间】:2023-02-19 22:48:19
【问题描述】:
我在我的 IAM 提供商处使用 Keycloak,并希望将 OpenResty 与 lua-resty-openidc 插件一起使用来为我所有的后端应用程序实施身份验证。 Openresty 将为我proxy_pass那些应用程序。
我几乎可以正常工作了,所以我只需要一些帮助就可以将其推向终点线。
这是我的设置:
我用 Access type: confidential 和 Valid Redirect URIs: *.mydomain.com 创建了一个 Keycloak 领域和一个客户端。这里没什么特别的,基本配置。
OpenResty 在我的 Kubernetes 集群中作为 Docker 容器运行,这是我用来构建镜像的 Dockerfile:
FROM openresty/openresty:alpine-fat
# install dependencies
RUN ["luarocks", "install", "lua-resty-session"]
RUN ["luarocks", "install", "lua-resty-http"]
RUN ["luarocks", "install", "lua-resty-jwt"]
RUN ["luarocks", "install", "lua-resty-openidc"]
EXPOSE 443
这是我的 Nginx 配置:
server_name cs.mydomain.com;
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
expires 0;
add_header Cache-Control private;
location / {
resolver kube-dns.kube-system.svc.cluster.local;
access_by_lua_block {
local opts = {
redirect_uri = "https://cs.mydomain.com/redirect_uri",
discovery = "https://keycloak.mydomain.com/realms/mdos/.well-known/openid-configuration",
client_id = "openresty",
client_secret = "<secret>",
scope = "openid",
redirect_uri_scheme = "https",
session_contents = {id_token=true}
}
local res, err = require("resty.openidc").authenticate(opts)
if err then
ngx.status = 403
ngx.say(err)
ngx.exit(ngx.HTTP_FORBIDDEN)
end
ngx.req.set_header("X-USER", res.id_token.sub)
}
proxy_pass http://my-app.openresty.svc.cluster.local:8080;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Host $host;
proxy_set_header Accept-Encoding gzip;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_headers_hash_bucket_size 128;
}
注意:如果我从配置文件中删除
access_by_lua_block块,我可以毫无问题地访问我的后端应用程序,因此我知道 Kubernetes / Openrestyproxy_pass配置在不使用 OIDC 身份验证的情况下按预期工作。此外,location部分中的resolver kube-dns.kube-system.svc.cluster.local;是必需的,因为我通常会通过一个变量来设置我的proxy_pass值,而不是像上面的示例那样对其进行硬编码,因为这会强制使用新的 DNS 解析集群,我必须告诉它使用什么 DNS 服务器,在这种情况下是内部 kubernetes 一个。值得注意的是,Keycloak 和 Openresty 是基于 TLS / HTTPS 的,具有有效的证书。在 kubernetes 中运行的后端应用程序是基于 HTTP 的。
那么当我尝试访问我的应用程序时会发生什么
我按预期被重定向到 keycloak 登录页面。然后我输入我的凭据并按回车键:
- 在 Firefox 上,我看到 Keycloak 页面显示“找不到页面”错误。
- 在 Chrome 上,我访问我的应用程序主页,但对域
cs.mydomain.com的所有子请求都会收到 404 错误(取自浏览器控制台错误)。当我刷新页面时,我最终进入了 keycloak 主页(可在https://keycloak.mydomain.com/下访问),但浏览器 url 指向cs.mydomain.com。我查看了 OpenResty 日志,里面什么都没有,就好像没有错误开始一样。使用 Chrome 直到我最初登陆我的目标应用程序时生成的日志:
82.169.48.99 - - [28/Jul/2022:11:25:08 +0000] "GET / HTTP/1.1" 302 151 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 192.169.29.71 - - [28/Jul/2022:11:25:19 +0000] "GET /redirect_uri?state=cd3c04ca2a84c3e9ce56d78072532989&session_state=550632d9-8b26-4fbd-aaa6-d184b829e812&code=89c8097d-ff4b-438c-95fd-738ccf16cf08.550632d9-8b26-4fbd-aaa6-d184b829e812.6eb80500-f1a7-4614-a638-652ad14cd44b HTTP/1.1" 302 151 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 192.169.29.71 - - [28/Jul/2022:11:25:19 +0000] "GET / HTTP/1.1" 200 1875 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 192.169.29.71 - - [28/Jul/2022:11:25:19 +0000] "GET /manifest.json HTTP/1.1" 200 230 "https://cs.mdundek.network/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"然后当我刷新页面并最终出现在 keycloak 主页时的日志,即使我的浏览器仍然指向
cs.mydomain.com:192.169.29.71 - - [28/Jul/2022:11:27:34 +0000] "GET /stable-30d9c6cd9483b2cc586687151bcbcd635f373630?type=Management&reconnectionToken=32942905-b0b2-4074-b801-75cacec311d6&reconnection=true&skipWebSocketFrames=false HTTP/1.1" 101 171 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 192.169.29.71 - - [28/Jul/2022:11:27:34 +0000] "GET /stable-30d9c6cd9483b2cc586687151bcbcd635f373630?type=ExtensionHost&reconnectionToken=26321ffb-cb7b-476a-81ec-c5847aa42822&reconnection=true&skipWebSocketFrames=false HTTP/1.1" 101 372 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 192.169.29.71 - - [28/Jul/2022:11:27:37 +0000] "GET /stable-30d9c6cd9483b2cc586687151bcbcd635f373630?type=Management&reconnectionToken=32942905-b0b2-4074-b801-75cacec311d6&reconnection=true&skipWebSocketFrames=false HTTP/1.1" 101 172 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 192.169.29.71 - - [28/Jul/2022:11:27:37 +0000] "GET /stable-30d9c6cd9483b2cc586687151bcbcd635f373630?type=ExtensionHost&reconnectionToken=26321ffb-cb7b-476a-81ec-c5847aa42822&reconnection=true&skipWebSocketFrames=false HTTP/1.1" 101 330 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"没有错误,不确定这里发生了什么。在这一点上,我什至不确定问题是出在 Keycloak 还是 Openresty 中。
【问题讨论】:
标签: nginx lua keycloak openresty lua-resty-openidc