53

so I have a problem getting keycloak 3.2.1 to work behind kong (0.10.3), a reverse proxy based on nginx.

Scenario is:

I call keycloak via my gateway-route via https://{gateway}/auth and it shows me the entrypoint with keycloak logo, link to admin console etc. - so far so good.

But when clicking on administration console -> calling https://{gateway}/auth/admin/master/console/ , keycloak tries to load its css/js via http (see screenie below), which my browser blocks because mixed content.

I searched around and found this thread: keycloak apache server configuration with 'Mixed Content' problems which lead to this github repo: https://github.com/dukecon/keycloak_postgres_https

From there on, I tried to integrate its' cli into my dockerfile with success (did not change the files' contents, just copied them into my repo and add/run them from dockerfile). This is my dockerfile right now:

FROM jboss/keycloak-postgres:3.2.1.Final

USER root

ADD config.sh /tmp/
ADD batch.cli /tmp/

RUN bash /tmp/config.sh

#Give correct permissions when used in an OpenShift environment.
RUN chown -R jboss:0 $JBOSS_HOME/standalone && \
    chmod -R g+rw $JBOSS_HOME/standalone

USER jboss
EXPOSE 8080

Sadly, my problem still exists: error

So I am out of ideas for now and hope you could help me out:

  • How do I tell keycloak to call its' css-files via https here?

  • do I have to change something in the cli script?

Here's the content of the script:

config.sh:

#!/bin/bash -x

set -e

JBOSS_HOME=/opt/jboss/keycloak
JBOSS_CLI=$JBOSS_HOME/bin/jboss-cli.sh
JBOSS_MODE=${1:-"standalone"}
JBOSS_CONFIG=${2:-"$JBOSS_MODE.xml"}

echo "==> Executing..."
cd /tmp

$JBOSS_CLI --file=`dirname "$0"`/batch.cli

# cf. http://stackoverflow.com/questions/34494022/permissions-error-when-using-cli-in-jboss-wildfly-and-docker
/bin/rm -rf ${JBOSS_HOME}/${JBOSS_MODE}/configuration/${JBOSS_MODE}_xml_history/current

and batch.cli:

embed-server --std-out=echo

# http://keycloak.github.io/docs/userguide/keycloak-server/html/server-installation.html
# 3.2.7.2. Enable SSL on a Reverse Proxy
# First add proxy-address-forwarding and redirect-socket to the http-listener element.
# Then add a new socket-binding element to the socket-binding-group element.

batch

/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)

/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket,value=proxy-https)

/socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)

run-batch

stop-embedded-server

It may be of interest too, that kong is deployed on openshift with a route using a redirect from http to https ( "insecureEdgeTerminationPolicy": "Redirect" ).

Dominik
  • 2,801
  • 2
  • 33
  • 45
  • Have you resolved this issue? Is there a working example I can take a look of? – NehaM Nov 22 '18 at 16:46
  • I faced the same with Keycloak 15.0.6 and got it resolved by adding `proxy-address-forwarding="true"` to default http-listener in standalone-ha.xml – wannix Jul 05 '22 at 18:51

7 Answers7

37

This sounds somehow like a duplicate of Keycloak Docker behind loadbalancer with https fails

Set the request headers X-Forwarded-For and X-Forwarded-Proto in nginx. Then you have to configure Keycloak (Wildfly, Undertow) to work together with the SSL terminating reverse proxy (aka load balancer). See http://www.keycloak.org/docs/latest/server_installation/index.html#_setting-up-a-load-balancer-or-proxy for a detailed description.

The point is that nginx is terminating SSL and is forwarding the requests to Keycloak as pure http. Therefore Keycloak/Wildfly must be told that the incoming http requests from nginx must be handled like they were https.

Boomer
  • 3,360
  • 20
  • 28
  • 1
    i'll check kong/nginx and accept the answer when I am sure (not my workbench atm, so it will require some time). Thanks so far! – Dominik Nov 09 '17 at 13:16
  • 1
    For anyone stuck in the same situation, i'll also let this hint here: Apart from the things Boomer described (actually, kong sends the proper headers per default), we had a problem with our openshift service, which was called via 8080. the standard port binding for 8080 in kc is http, so kc served http. We changed our openshift config to use 8443, et voila. worked. :) – Dominik Nov 15 '17 at 13:38
  • 3
    Somewhat unrelated question, how does Keycloak resolve its base url? We have a Keycloak istance with a public and private ip address and the `iss` field of the JWT bearer token (which is the realm url) changes accordingly, i.e. if we hit the auth endpoint from public address the `iss` field is `public-ip/realms/master` and from private ip address it's `private-ip/realms/master`. Is this some HTTP magic or a Kycloak config? Docs mention setting up reverse proxy but this is a different case I suppose. – Nader Ghanbari Mar 23 '19 at 03:54
  • 3
    For newcomers arriving here after trying everything in the docs and all the solutions on stackoverflow and still having problems with mixed content: Setting the [KEYCLOAK_FRONTEND_URL](https://stackoverflow.com/a/61502091/385571) environment variable was that finally fixed it for me – MattBianco Apr 29 '20 at 12:49
34

Add the X-Forwarded-For and X-Forwarded-Proto headers (as Boomer said) in all upstream load balancers and make sure those reach Keycloak server. X-Forwarded-For should be the domain of your Keycloak which routes to the LB and X-Forwarded-Proto should be the protocol (most of the cases https).

As a final step you need to modify standalone.xml or standalone-ha.xml file and add the proxy-address-forwarding="true" attribute to <http-listener> element under <server>.

If you are using Docker you can use PROXY_ADDRESS_FORWARDING environment var from the original Keycloak container to set this attribute.

László Szabó
  • 391
  • 4
  • 5
  • any idea on this https://stackoverflow.com/questions/48513451/keycloak-with-nginx-proxy-server-not-authenticating-rest-api?noredirect=1#comment84046838_48513451? – ksernow Feb 01 '18 at 00:34
11

To elaborate on the reply from @MattBianco. In modern Keycloak variables you need to set KEYCLOAK_FRONTEND_URL to https:///auth. Using docker you can set this as an environment variable e.g. KEYCLOAK_FRONTEND_URL=https://auth.foo.com/auth

jwanga
  • 4,166
  • 4
  • 26
  • 27
10

If you're using Keycloak.X (Quarkus version of Keycloak), then those solutions will not work.

You have to set environment variable KC_PROXY=edge (as per https://github.com/keycloak/keycloak-community/blob/master/design/keycloak.x/configuration.md).

brunobastosg
  • 1,380
  • 19
  • 31
7

I have the same problem with you, now it fixed, This is my method.

First, I setup reverse proxy with cloak at a clean env, confirm that the proxy and cloak was configured rightly.

Next, with test and gusess, I found when setup keycloak use the image you pull from dockerhub whith docker. There is some difference set it up with binary on server, from the standalone.xml, you will find the key point is this 2:

1. You should set PROXY_ADDRESS_FORWARDING=true for docker env.

2. You should set jboss.https.port 443 for docker env.

If your standalone.xml also configured rightly, you will get it work for admin page. Good lucks ;)

HuBaoQi
  • 71
  • 1
  • 2
  • Setting those 2 env variables in `docker-compose` solved the problem for me. No need to edit the `standalone.xml` file. – hurb Mar 24 '20 at 18:41
  • 8
    For newcomers (2020) arriving here after trying everything in the docs and all the solutions on stackoverflow and still having problems with mixed content: Setting the [KEYCLOAK_FRONTEND_URL](https://stackoverflow.com/a/61502091/385571) environment variable was that finally fixed it for me – MattBianco Apr 29 '20 at 12:50
  • Thank you @MattBianco! You saved my day/night. Actually, it not only worked, but you also have described the whole scene perfectly. – Reginaldo Santos Oct 02 '20 at 04:14
4

Two tips :

If you use a docker-compose.yml, add the following env variable to the keycloak container:

environment:
  PROXY_ADDRESS_FORWARDING: "true"

Restart the stack, check if the variable is there (sometimes you have to restart several times the container)

docker-compose exec keycloak bash -c 'echo $PROXY_ADDRESS_FORWARDING'

If you use an Apache container as a proxy (with mod_proxy) you should add manually the X-Forwarded-Proto and X-Forwarded-Port headers:

<IfModule mod_ssl.c>

# Proxy pass for keycloak
<VirtualHost *:443>
    ServerName auth.myproject_url.tld
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
    SSLCertificateKeyFile /etc/ssl/certs/apache-selfsigned.key
    <IfModule mod_proxy.c>
        SSLProxyEngine on
        <Location "/">
            ProxyPass  "http://keycloak:8080/"
            ProxyPassReverse "http://keycloak:8080/"
            RequestHeader set X-Forwarded-Proto "https"
            RequestHeader set X-Forwarded-Port "443"
            #  ProxyPreserveHost On
        </Location>
    </IfModule>
    </IfModule>
</VirtualHost>
Teenage
  • 210
  • 2
  • 6
2

After much struggle I found alternative solution using X-Forwarded-Host in addition to other headers. This is undocumented however it works, and seems to be working quite long time ago already. Check this pull request https://github.com/wildfly/wildfly/pull/5593

Keycloak documentation at https://www.keycloak.org/docs/latest/server_installation mentions that for proxy forwarding you need to set PROXY_ADDRESS_FORWARDING=true as docker arg plus X-Forwarded-For, X-Forwarded-Proto and original Host (host of internet facing proxy in my case).

But setting original Host was not possible in my case, because I'm hosting Keycloak in Azure app service. Actually the main issue it was not working because proxy sent requests with keycloak internal Host header, which is the only way it will work in my case.

Azure app gateway is using X-ORIGINAL-HOST, but X-Forwarded-Host seems to be more widely used header for original host name. I've tried setting X-Forwarded-Host at my proxy and finally it worked, although this approach is not mentioned in documentation. Check also this discussion https://keycloak.discourse.group/t/x-forwarded-host-proxy-header-support/10730

snautz
  • 521
  • 4
  • 5