I have surfed through google without finding any concrete answers or examples, so again trying my luck here (often get lucky).
I tried different things, but could not solve the problem. To me it seems like there is not way to specify auth-server-url: http://172.k:9080/auth
in the backend adapter while the frontend adapter is putting auth-server-url:https://example.com/auth
in the token. So my solution was to configure all the backend services to also the auth-server-url: https://example.com/auth
.
The only disadvantage of this is that my backend service adapter communicates with keycloak over web, which probably is not so good performance wise, but at least everything works as it should. It should have been possible to somehow specify a local keycloak endpoint within the same local network, or the same VPN in AWS.
You need to inform keycloak about the location of the reverse proxy. Then in its response it will set location to there instead of its local address. To do that in the latest keycloak set the environment variable 'KEYCLOAK_FRONTEND_URL' to point to
the string https://example.com/auth
(yes, it needs the whole address.
To make this work, also set PROXY_ADDRESS_FORWARDING
to the value true
If it's a Docker container, that means:
environment:
...
PROXY_ADDRESS_FORWARDING: "true"
KEYCLOAK_FRONTEND_URL: "https://example.com/auth"
Alternately, you can set KEYCLOAK_HOSTNAME
to example.com
and that will leave the port number, for which???(not sure how to do this part yet, if you find out please let me know... ) )
One of the solutions is to upgrade the adapter to 8.0.0. This problem seems to be fixed in version 8.0.0.
It was known problem KEYCLOAK-6073:
Add support for OpenID Connect Discovery to Java adapters... Adapters should support using different URLs for frontend and backend requests.
I've had a similar problem in a docker swarm environment. My Keycloak and my spring boot container were both behind the same reverse proxy.
For Tomcat: The matter is to configure the http(s) connector correctly. Let's say the host name and port of our reverse proxy are http://${EXTERNAL_HOSTNAME}:${EXTERNAL_PORT}.
Then the http(s) connector in tomcat.xml should have those two additional attributes:
<Connector [...] proxyName="${EXTERNAL_HOSTNAME}" proxyPort="${EXTERNAL_PORT}"/>
This will make all calls to servletRequest.getServerName() and servletRequest.getServerPort() respond with the values of our reverse proxy. The keycloak adapter certainly uses these functions to determine the redirect url.
For Spring Boot: Drop this class in your classpath:
@Component
public class TomcatReverseProxyCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, TomcatConnectorCustomizer {
@Value("${server.tomcat.proxy-name}")
private String proxyName;
@Value("${server.tomcat.proxy-port}")
private int proxyPort;
@Override
public void customize(final TomcatServletWebServerFactory factory) {
factory.addConnectorCustomizers(this);
}
@Override
public void customize(final Connector connector) {
connector.setProxyName(this.proxyName);
connector.setProxyPort(this.proxyPort);
}
}
and then setting this in application.properties:
server.tomcat.proxy-name=${EXTERNAL_HOSTNAME}
server.tomcat.proxy-port=${EXTERNAL_PORT}
Additional Configuration of the keycloak adapter (Examples are for Spring Boot):
My keycloak is also behind the same reverse proxy. So I also had to set the auth server url of the keycloak adapter to the hostname of the reverse proxy. Then I abused the proxy setting of the keycloak adapter to make it use the services on the internal leg:
keycloak.auth-server-url=http://${EXTERNAL_HOSTNAME}:${EXTERNAL_PORT}/auth
keycloak.proxy-url=http://${INTERNAL_KEYCLOAK_HOSTNAME}:${INTERNAL_KEYCLOAK_PORT}/auth
Also these settings might make some sense:
server.servlet.session.cookie.domain=${EXTERNAL_HOSTNAME}
server.use-forward-headers=true
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.protocol-header is important for those who terminate SSL on their reverse proxy.
I'm using Keycloak for a project in docker containers. I had the same problem but in a local network (so maybe this will not be the solution, in this case i'm sorry). So this was the situation:
Apache running locally on my machine outside Docker, serving an angular 2 app, with the properly config
The angular 2 app's adapter was pointing the url http://aaa.auth.com (i modified the local file hosts with the entry 127.0.0.1 aaa.auth.com)
There are a lot of differences from your case (Docker, HTTP vs HTTPS etc), but, to avoid the communication REST-Keycloak via Web, have you tried modifying the file hosts of your server (hosting the RESTful service) inserting an entry with the local IP of your reverse proxy (172.a) and "example.com"?
Or, maybe you can solve it with a private DNS?