lua-resty-openidc
lua-resty-openidc copied to clipboard
TLS termination use case
Hello everyone,
I'm trying to setup a TLS terminating nginx configuration where the TLS terminated nginx server listening on port 80 will do the openidc authentication, and redirect them to the secured static content. Any help is appreciated.
Thank you.
Environment
- lua-resty-openidc version (1.7.6)
- OpenID Connect provider: Keycloak image (quay.io/keycloak/keycloak:23.0) I'm running the setup in docker-compose with keycloak being a service, and nginx with the provided configuration further below.
Expected behavior
This setup is basically a login/logout cycle on an nginx server serving static content.
- The user will login via clicking a login link in the home page that will take them to the keycloak login page (username, password etc.)
- User authenticates, and lua-resty-openidc will handle redirecting them to a protected app page (static content on the nginx server).
- When the user logs out via the logout button on the home page, the user will be redirected to the home page.
Actual behavior
- The user is sent to keycloak login screen after pressing the login link on the main page.
- After the authentication, I am redirected to openresty 404 page with the uri: https://${HOME_DOMAIN}/auth?state=b6b178fc48d14abdcb65f92e62adb25a&session_state=75cc0f5f-a2bd-405b-9bc3-67c634028c4e&iss=https%3A%2F%2F${KEYCLOAK_INTERNAL_URL}%2Frealms%2F${KEYCLOAK_REALM}&code=4959cd9c-e162-46d2-ad25-3268966efcbc.75cc0f5f-a2bd-405b-9bc3-67c634028c4e.b2a4ca15-b77f-4a3f-ae99-bdddcfd8f332
Based off of what I read from 240, I think this is a right use case of redirect uri. I suspect there might be something going on with the redirect_uri (I don't have a redirect_uri for this basic configuration, and I've just left it as a uri that keycloak validates against to make sure it gets redirected to the right uri).
Minimized example
Minimal, complete configuration that reproduces the behavior. Here is my nginx configuration and Dockerfile.dev
FROM openresty/openresty:alpine-fat
RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-http\
&& /usr/local/openresty/luajit/bin/luarocks install lua-resty-session\
&& /usr/local/openresty/luajit/bin/luarocks install lua-resty-jwt\
&& /usr/local/openresty/luajit/bin/luarocks install lua-resty-openidc
# the configuration lives under /usr/local/openresty/nginx/conf/nginx.conf in the container
worker_processes auto;
events {
worker_connections 128;
}
http {
include mime.types;
default_type application/octet-stream;
# lua-resty-openidc required http context config
lua_package_path '~/lua/?.lua;;';
resolver ${LUA_RESTY_NGINX_RESOLVER};
# cache for discovery metadata documents
lua_shared_dict discovery 1m;
# cache for JWKs
lua_shared_dict jwks 1m;
# tls server settings
keepalive_timeout 70;
error_log stderr debug;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# reduce processor load when using tls
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# global proxy settings
proxy_buffering on;
proxy_buffer_size 256k;
proxy_buffers 4 512k;
proxy_http_version 1.1;
# Pretend to be a reverse proxy in front of our oidc auth and application
server {
listen ${PROXY_PORT} ssl;
server_name ${HOME_DOMAIN};
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# Redirect from http to https.
error_page 497 301 =307 https://$host:$server_port$request_uri;
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
root /var/www/html/home;
location / {
}
location /app {
return 302 /app/;
}
location /app/ {
proxy_set_header Host $host;
proxy_pass http://localhost:80/;
}
}
# Do OIDC auth when our endpoint is hit
server {
listen 80;
server_name ${HOME_DOMAIN};
allow 127.0.0.1;
deny all;
location / {
proxy_set_header Host ${HOME_DOMAIN}.internal;
proxy_pass http://localhost:80/;
access_by_lua_block {
local opts = {
client_id="${CLIENT_ID}",
client_secret="${CLIENT_SECRET}",
ssl_verify="${OPENIDC_SERVER_VERIFY}",
redirect_uri = "https://${HOME_DOMAIN}/auth",
logout_path = "/logout",
post_logout_redirect_uri = "https://${HOME_DOMAIN}/",
use_pkce = true,
discovery = "${KEYCLOAK_INTERNAL_URL}/realms/${KEYCLOAK_REALM}/.well-known/openid-configuration"
}
local openidc = require("resty.openidc")
openidc.set_logging(ngx.log, { DEBUG = ngx.INFO })
local res, err = openidc.authenticate(opts)
if err then
ngx.status = 500
ngx.say(err)
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
ngx.req.set_header("X-USER", res.id_token.sub)
}
}
}
# Serve the application
server {
listen 80;
server_name ${HOME_DOMAIN}.internal;
allow 127.0.0.1;
deny all;
root /var/www/html/app;
location / {
}
}
}
Configuration and NGINX server log files
Config and logs for the minimized example, possibly provided as attachments.
2024-02-05 11:07:29 172.28.0.4 - - [05/Feb/2024:18:07:29 +0000] "GET /app HTTP/1.1" 302 151 "https://${HOME_DOMAIN}/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:1520: authenticate(): session.present=nil, session.data.id_token=false, session.data.authenticated=nil, opts.force_reauthorize=nil, opts.renew_access_token_on_expiry=nil, try_to_renew=true, token_expired=false, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:556: openidc_discover(): openidc_discover: URL is: https://${KEYCLOAK_INTERNAL_URL}/realms/${KEYCLOAK_REALM}/.well-known/openid-configuration, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:107: openidc_cache_get(): cache hit: type=discovery key=https://${KEYCLOAK_INTERNAL_URL}/realms/${KEYCLOAK_REALM}/.well-known/openid-configuration, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:674: openidc_get_token_auth_method(): 1 => private_key_jwt, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:64: supported(): Can't use private_key_jwt without opts.client_rsa_private_key, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:674: openidc_get_token_auth_method(): 2 => client_secret_basic, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:677: openidc_get_token_auth_method(): no configuration setting for option so select the first supported method specified by the OP: client_secret_basic, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:691: openidc_get_token_auth_method(): token_endpoint_auth_method result set to client_secret_basic, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}l/"
2024-02-05 11:07:29 2024/02/05 18:07:29 [info] 10#10: *17 [lua] openidc.lua:1551: authenticate(): Authentication is required - Redirecting to OP Authorization endpoint, client: 127.0.0.1, server: ${HOME_DOMAIN}, request: "GET / HTTP/1.1", host: "${HOME_DOMAIN}", referrer: "https://${HOME_DOMAIN}/"
2024-02-05 11:07:29 127.0.0.1 - - [05/Feb/2024:18:07:29 +0000] "GET / HTTP/1.1" 302 151 "https://${HOME_DOMAIN}/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
2024-02-05 11:07:29 172.28.0.4 - - [05/Feb/2024:18:07:29 +0000] "GET /app/ HTTP/1.1" 302 151 "https://${HOME_DOMAIN}/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
2024-02-05 11:07:33 2024/02/05 18:07:33 [error] 14#14: *13 open() "/var/www/html/home/auth" failed (2: No such file or directory), client: 172.28.0.4, server: ${HOME_DOMAIN}, request: "GET /auth?state=73290099b5e81f7cb4c40a8086c1dcd9&session_state=75cc0f5f-a2bd-405b-9bc3-67c634028c4e&iss=https%3A%2F%2F${KEYCLOAK_INTERNAL_URL}%2Frealms%2F${KEYCLOAK_REALM}&code=c7750501-6fe2-4a72-9956-e9d02672dff3.75cc0f5f-a2bd-405b-9bc3-67c634028c4e.b2a4ca15-b77f-4a3f-ae99-bdddcfd8f332 HTTP/1.1", host: "${HOME_DOMAIN}"
2024-02-05 11:07:33 172.28.0.4 - - [05/Feb/2024:18:07:33 +0000] "GET /auth?state=73290099b5e81f7cb4c40a8086c1dcd9&session_state=75cc0f5f-a2bd-405b-9bc3-67c634028c4e&iss=https%3A%2F%2F${KEYCLOAK_INTERNAL_URL}%2Frealms%2F${KEYCLOAK_REALM}&code=c7750501-6fe2-4a72-9956-e9d02672dff3.75cc0f5f-a2bd-405b-9bc3-67c634028c4e.b2a4ca15-b77f-4a3f-ae99-bdddcfd8f332 HTTP/1.1" 404 561 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"