0

I have a Spring Boot + Spring Security application with RedhatSSO (Keycloak) as OIDC provider. This application is deployed on Openshift which assings it a route like this: http://my-app.cloud.mycompany.com/. The application has this context path: /my-app.

When I access a protected resource using the application's Openshift route address, http://my-app.cloud.mycompany.com/my-app/someProtectedResource, I am redirected to the Keycloak login page https://sso.mycompany.com where I login and I'm sent back to http://my-app.cloud.mycompany.com/my-app/sso/login. Then it exchanges the code for an access token and works without any problem allowing the access to the protected path.

However this isn't our target scenario since all applications are accessed through an Apache server with this url http://intranet.mycompany.com.

When I enter http://intranet.mycompany.com/my-app/someProtectedResource the request gets to my-app's pod in Openshift which redirects to the login form in https://sso.mycompany.com. BUT the URL the param redirect_uri is pointing at the application's Openshift route address http://my-app.cloud.mycompany.com/my-app/sso/login instead of http://intranet.mycompany.com/my-app/sso/login:

16:38:21,634 DEBUG [org.keycloak.adapters.OAuthRequestAuthenticator] (default task-59) there was no code
16:38:21,634 DEBUG [org.keycloak.adapters.OAuthRequestAuthenticator] (default task-59) redirecting to auth server
16:38:21,634 DEBUG [org.keycloak.adapters.OAuthRequestAuthenticator] (default task-59) callback uri: http://my-app.cloud.mycompany.com/my-app/sso/login

This way, after successfully logging in I am sent to the wrong address and the single sign on fails.

I am using this configuration:

Gradle:

springBootVersion = '1.5.10.RELEASE'
keycloakVersion = '3.4.3.Final'
...
mavenBom "org.keycloak.bom:keycloak-adapter-bom:${keycloakVersion}"
...
compile 'org.keycloak:keycloak-spring-boot-starter',
        'org.keycloak:keycloak-spring-security-adapter',

Spring Boot:

keycloak:
  auth-server-url: https://sso.mycompany.com/auth
  realm: MYREALM
  resource: my-app
  public-client: false
  principal-attribute: preferred_username
  credentials:
    secret: 99988877766655555444333
  autodetect-bearer-only: true
  ssl-required: external

How can I make the application realize its actual redirect_uri should have intranet.mycompany.com when it is behind an Apache Server?

codependent
  • 23,193
  • 31
  • 166
  • 308
  • It seems like your application isn't noticing that it's behind a reverse proxy when you call it. Verify you've got apache properly configured to send the `X-Forwarded-Host` header. – Aritz Mar 04 '18 at 19:00
  • Hi, `X-Forwarded-Host` is being sent by Apache but Keycloak's adapter doesn't take it into account: `OAuthRequestAuthenticator` does this without looking for that header at all: `getRedirectUri()` -> `facade.getRequest().getURI()`. – codependent Mar 04 '18 at 23:02

1 Answers1

0

We are using two kinds of Spring Boot applications and solved this for both of them:

First off this is the necessary Apache configuration:

RequestHeader set "Host" "intranet.mycompany.com"
UseCanonicalName on
ProxyPreserveHost on

ProxyPass /my-app http://my-app.cloud.mycompany.com/my-app
ProxyPassreverse /my-app http://my-app.cloud.mycompany.com/my-app

Spring Boot jar running on Tomcat:

To make the server use the X-Fowarded-* headers just add:

server:
  context-path: /my-app
  use-forward-headers: true

Spring Boot war running on JBoss:

Update your standalone.xml setting proxy-address-forwarding="true":

<http-listener name="default" proxy-address-forwarding="true" socket-binding="http" redirect-socket="https"/>
codependent
  • 23,193
  • 31
  • 166
  • 308