问题
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?
回答1:
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"/>
来源:https://stackoverflow.com/questions/49072470/spring-boot-application-using-keycloak-single-sign-on-doesnt-work-behind-an-ap