I set up a NodeJS Server to use the keycloak-connect module:
// Setup keycloak to use the session memoryStore
var memoryStore = new SESSION.MemoryStore();
var keycloak = new KEYCLOAK({ store: memoryStore });
// Set up a server instance and create a session middleware
const APP = EXPRESS();
APP.use(SESSION({
secret: CRYPTO.randomBytes(512).toString('hex'),
resave: false,
saveUninitialized: true,
store: memoryStore
}));
// Default route handler
APP.get('/login', keycloak.protect(), function(req, res) {
...some custom logic, involving AXIOS XHR stuff
...getting tokens from REST endpoints
res.redirect('/app/html/createCustomer?' +
QUERYSTRING.encode({'tokenId': tokenID}));
}
APP.use(keycloak.middleware( { logout: '/logout'}));
// Start servers
HTTP.createServer(APP).listen(CONF.serverPort, CONF.serverInterface, () =>
console.log('Server listening on %s:%d', CONF.serverInterface,
CONF.serverPort));
The CONF objects holds CONF.serverPort=9080 and CONF.serverInterface=127.0.0.1
The keycloak.json reads
{
"realm": "app-realm",
"auth-server-url": "https://192.168.32.132/auth",
"ssl-required": "external",
"resource": "app-client",
"public-client": true,
"confidential-port": 0
}
Both NodeJS and Keycloak Docker Container are binding to 127.0.0.1, living behind an nginx
revrse proxy.
The nginx reverse proxy uses TLS and terminates all HTTPS, sending all traffic to those
upstream servers via plain HTTP.
The configuration of nginx reads
server {
listen 80;
listen [::]:80;
server_name 192.168.32.132;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name 192.168.32.132;
ssl_certificate /etc/ssl/private/fullchain.pem;
ssl_certificate_key /etc/ssl/private/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location /login {
proxy_pass
http://127.0.0.1:9080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /auth {
proxy_pass
http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /app {
rewrite ^/app(.*)$ $1 last;
proxy_pass
http://127.0.0.1:7080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Additionally, the following lines are added for EVERY location block:
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
There is a realm, a client with redirect URIs set to WILDCARD and one user.
Accessing route /login always leads to a redirect loop.
Following the HTTP stream via WireShark yields these results:
GET /login HTTP/1.1
Host: 192.168.32.132
Upgrade-Insecure-Requests: 1
HTTP/1.1 301 Moved Permanently
Server: nginx
Location:
https://192.168.32.132/login
Strict-Transport-Security: max-age=31536000; includeSubdomains;
GET
/login?auth_callback=1&state=eb22b4f5-e262-4deb-8e7d-f483ec1af553&session_state=9759ce64-400e-4e53-8cf5-613b2409a1c1&code=854efde1-71dc-4052-a0ad-7503ea3af7e4.9759ce64-400e-4e53-8cf5-613b2409a1c1.c00e43ce-79c2-48ee-8b92-639a6c9ade44
HTTP/1.1
Host: 192.168.32.132
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Cookie:
connect.sid=s%3AhkFnuXd3uHPZym3mvFd2v6v2_bEmOYCm.jAeQvvN%2FZP7%2F9hV77wBI80pi%2B7T9CJo4LENc9kF5eSc
HTTP/1.1 301 Moved Permanently
Server: nginx
Location:
https://192.168.32.132/login?auth_callback=1&state=eb22b4f5-e262-4deb...
Strict-Transport-Security: max-age=31536000; includeSubdomains;
GET
/login?auth_callback=1&state=eb22b4f5-e262-4deb-8e7d-f483ec1af553&session_state=9759ce64-400e-4e53-8cf5-613b2409a1c1&code=854efde1-71dc-4052-a0ad-7503ea3af7e4.9759ce64-400e-4e53-8cf5-613b2409a1c1.c00e43ce-79c2-48ee-8b92-639a6c9ade44&auth_callback=1&state=30d7d290-e967-488d-887c-b6eec1cc5d27&session_state=9759ce64-400e-4e53-8cf5-613b2409a1c1&code=089d3ff9-702f-430c-9e97-f0aa5b9ae0a3.9759ce64-400e-4e53-8cf5-613b2409a1c1.c00e43ce-79c2-48ee-8b92-639a6c9ade44
HTTP/1.1
Host: 192.168.32.132
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Cookie:
connect.sid=s%3AhkFnuXd3uHPZym3mvFd2v6v2_bEmOYCm.jAeQvvN%2FZP7%2F9hV77wBI80pi%2B7T9CJo4LENc9kF5eSc
HTTP/1.1 301 Moved Permanently
Server: nginx
Location:
https://192.168.32.132/login?auth_callback=1&state=eb22b4f5-e262-4deb...
Strict-Transport-Security: max-age=31536000; includeSubdomains;
GET
/login?auth_callback=1&state=eb22b4f5-e262-4deb-8e7d-f483ec1af553&session_state=9759ce64-400e-4e53-8cf5-613b2409a1c1&code=854efde1-71dc-4052-a0ad-7503ea3af7e4.9759ce64-400e-4e53-8cf5-613b2409a1c1.c00e43ce-79c2-48ee-8b92-639a6c9ade44&auth_callback=1&state=30d7d290-e967-488d-887c-b6eec1cc5d27&session_state=9759ce64-400e-4e53-8cf5-613b2409a1c1&code=089d3ff9-702f-430c-9e97-f0aa5b9ae0a3.9759ce64-400e-4e53-8cf5-613b2409a1c1.c00e43ce-79c2-48ee-8b92-639a6c9ade44&auth_callback=1&state=d60d22a4-7098-4f6c-8974-0fd98d65d247&session_state=9759ce64-400e-4e53-8cf5-613b2409a1c1&code=27f41194-4dda-412c-b35c-f3e4ad9f987a.9759ce64-400e-4e53-8cf5-613b2409a1c1.c00e43ce-79c2-48ee-8b92-639a6c9ade44
HTTP/1.1
Host: 192.168.32.132
etc.
What is the problem with the server setup ?