If you want keycloak to handle auth requests in the same domain as you’re service your single page app (spa) and http api:
The prerender config comes from my prerendering proxy.
Keycloak is listening on port 4000 locally.
nginx config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name domain.tld; ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem; access_log /var/log/nginx/domain.tld.access.log; error_log /var/log/nginx/domain.tld.error.log; root /var/www/domain.tld/htdocs; index index.html; location / { try_files $uri $uri/ @prerender; } location @prerender { proxy_set_header Host $host; if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") { set $prerender 0; } if ($prerender = 1) { proxy_pass http://127.0.0.1:9292; } if ($prerender = 0) { rewrite .* /index.html break; } } location /auth/ { proxy_pass http://127.0.0.1:4000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffer_size 64k; proxy_buffers 8 64k; proxy_busy_buffers_size 64k; } location /api/ws/notify { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; rewrite ^/(.*)$ /$1 break; proxy_set_header Host localhost; proxy_pass http://unix:/tmp/kotzerei.sock; } location ~ ^/api/v1/.* { proxy_pass http://unix:/tmp/domain.tld-proxy.sock; proxy_read_timeout 30; proxy_connect_timeout 30; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } |
You mount keycloak under /auth/
Then in keycloak.yml for the gatekeeper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
discovery-url: https://domain.tld/auth/realms/domain.tld client-id: web-client listen: unix:///tmp/domain.tld-proxy.sock enable-refresh-tokens: true encryption-key: 32-characters-long-key012345678 upstream-url: unix:///tmp/domain.tld.sock secure-cookie: true no-redirects: true verbose: false cors-origins: ['*'] cors-methods: [GET, POST, PUT, OPTIONS, DELETE] cors-headers: ['*'] resources: - uri: /api/v1/* methods: - GET - HEAD - OPTIONS white-listed: true - uri: /api/v1/* methods: - DELETE - PATCH - POST - PUT - TRACE |
And if using Angular with PWA
1 2 3 4 5 6 7 |
"navigationUrls": [ "/**", "!/**/*.*", "!/**/*__*", "!/**/*__*/**", "!/auth/**" ], |
need to be added to the root {}
to exclude treating the /auth/ prefix path as an angular internal route.
So it looks something like this for the default config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
{ "$schema": "./node_modules/@angular/service-worker/config/schema.json", "index": "/index.html", "navigationUrls": [ "/**", "!/**/*.*", "!/**/*__*", "!/**/*__*/**", "!/auth/**" ], "assetGroups": [ { "name": "app", "installMode": "prefetch", "resources": { "files": [ "/favicon.ico", "/index.html", "/manifest.webmanifest", "/*.css", "/*.js" ] } }, { "name": "assets", "installMode": "lazy", "updateMode": "prefetch", "resources": { "files": [ "/assets/**", "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)" ] } } ] } |
And now you have keycloak running under the same domain as your SPA and http api.