KEYCLOAK-720 Support for relative URI resolved by hostname in wildfly adapter

This commit is contained in:
mposolda committed 2014-09-30 17:37:36 +02:00
1 parent 337b03fc62
commit 18fe808ce0
6 files changed
+142 -30

No files matched your search

@@ -42,7 +42,7 @@ public class AdminClient {
HttpClient client = new HttpClientBuilder()
.disableTrustManager().build();
try {
HttpGet get = new HttpGet(getBaseUrl(req) + "/auth/admin/realms/demo/roles");
HttpGet get = new HttpGet(CustomerDatabaseClient.getBaseUrl(req, session) + "/auth/admin/realms/demo/roles");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
@@ -64,9 +64,4 @@ public class AdminClient {
}
}
public static String getBaseUrl(HttpServletRequest request) {
String url = request.getRequestURL().toString();
return url.substring(0, url.indexOf('/', 8));
}
}
@@ -6,8 +6,12 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.HttpClientBuilder;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.enums.RelativeUrlsUsed;
import org.keycloak.representations.IDToken;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.UriUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@@ -48,7 +52,7 @@ public class CustomerDatabaseClient {
HttpClient client = new HttpClientBuilder()
.disableTrustManager().build();
try {
HttpGet get = new HttpGet(getBaseUrl(req) + "/database/customers");
HttpGet get = new HttpGet(getBaseUrl(req, session) + "/database/customers");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
@@ -70,8 +74,23 @@ public class CustomerDatabaseClient {
}
}
public static String getBaseUrl(HttpServletRequest request) {
String url = request.getRequestURL().toString();
return url.substring(0, url.indexOf('/', 8));
public static String getBaseUrl(HttpServletRequest request, KeycloakSecurityContext session) {
if (session instanceof RefreshableKeycloakSecurityContext) {
KeycloakDeployment deployment = ((RefreshableKeycloakSecurityContext)session).getDeployment();
switch (deployment.getRelativeUrls()) {
case ALL_REQUESTS:
// Resolve baseURI from the request
return UriUtils.getOrigin(request.getRequestURL().toString());
case BROWSER_ONLY:
// Resolve baseURI from the codeURL (This is already non-relative and based on our hostname)
return UriUtils.getOrigin(deployment.getCodeUrl());
case NEVER:
return "";
default:
return "";
}
} else {
return UriUtils.getOrigin(request.getRequestURL().toString());
}
}
}
@@ -7,5 +7,6 @@
"expose-token": true,
"credentials": {
"secret": "password"
}
},
"use-hostname-for-local-requests": false
}
@@ -5,6 +5,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.jboss.logging.Logger;
import org.keycloak.enums.RelativeUrlsUsed;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.representations.idm.PublishedRealmRepresentation;
@@ -48,14 +49,23 @@ public class AdapterDeploymentContext {
KeycloakDeployment deployment = this.deployment;
if (deployment == null) return null;
if (deployment.getAuthServerBaseUrl() == null) return deployment;
if (deployment.relativeUrls) {
deployment = new DeploymentDelegate(this.deployment);
deployment.setAuthServerBaseUrl(getBaseBuilder(facade, this.deployment.getAuthServerBaseUrl()).build().toString());
}
deployment = resolveUrls(deployment, facade);
if (deployment.getRealmKey() == null) resolveRealmKey(deployment);
return deployment;
}
protected KeycloakDeployment resolveUrls(KeycloakDeployment deployment, HttpFacade facade) {
if (deployment.relativeUrls == RelativeUrlsUsed.NEVER) {
// Absolute URI are already set to everything
return deployment;
} else {
DeploymentDelegate delegate = new DeploymentDelegate(this.deployment);
delegate.setAuthServerBaseUrl(getBaseBuilder(facade, this.deployment.getAuthServerBaseUrl()).build().toString());
return delegate;
}
}
protected void resolveRealmKey(KeycloakDeployment deployment) {
if (deployment.getClient() == null) {
throw new RuntimeException("KeycloakDeployment was never initialized through appropriate SPIs");
@@ -107,6 +117,46 @@ public class AdapterDeploymentContext {
this.delegate = delegate;
}
public void setAuthServerBaseUrl(String authServerBaseUrl) {
this.authServerBaseUrl = authServerBaseUrl;
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
resolveBrowserUrls(serverBuilder);
if (delegate.getRelativeUrls() == RelativeUrlsUsed.ALL_REQUESTS) {
resolveNonBrowserUrls(serverBuilder);
}
}
@Override
public RelativeUrlsUsed getRelativeUrls() {
return delegate.getRelativeUrls();
}
@Override
public String getRealmInfoUrl() {
return (this.realmInfoUrl != null) ? this.realmInfoUrl : delegate.getRealmInfoUrl();
}
@Override
public String getCodeUrl() {
return (this.codeUrl != null) ? this.codeUrl : delegate.getCodeUrl();
}
@Override
public String getRefreshUrl() {
return (this.refreshUrl != null) ? this.refreshUrl : delegate.getRefreshUrl();
}
@Override
public KeycloakUriBuilder getLogoutUrl() {
return (this.logoutUrl != null) ? this.logoutUrl : delegate.getLogoutUrl();
}
@Override
public String getAccountUrl() {
return (this.accountUrl != null) ? this.accountUrl : delegate.getAccountUrl();
}
@Override
public String getResourceName() {
return delegate.getResourceName();
@@ -1,9 +1,13 @@
package org.keycloak.adapters;
import org.apache.http.client.HttpClient;
import org.jboss.logging.Logger;
import org.keycloak.ServiceUrlConstants;
import org.keycloak.enums.RelativeUrlsUsed;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.util.KeycloakUriBuilder;
import org.keycloak.util.UriUtils;
import java.net.URI;
import java.security.PublicKey;
@@ -16,10 +20,11 @@ import java.util.Map;
*/
public class KeycloakDeployment {
protected boolean relativeUrls;
private static final Logger log = Logger.getLogger(KeycloakDeployment.class);
protected RelativeUrlsUsed relativeUrls;
protected String realm;
protected PublicKey realmKey;
protected KeycloakUriBuilder serverBuilder;
protected String authServerBaseUrl;
protected String realmInfoUrl;
protected KeycloakUriBuilder authUrl;
@@ -76,26 +81,62 @@ public class KeycloakDeployment {
return authServerBaseUrl;
}
public void setAuthServerBaseUrl(String authServerBaseUrl) {
public void setAuthServerBaseUrl(String authServerBaseUrl, AdapterConfig config) {
this.authServerBaseUrl = authServerBaseUrl;
if (authServerBaseUrl == null) return;
URI uri = URI.create(authServerBaseUrl);
if (uri.getHost() == null) {
relativeUrls = true;
return;
if (config.isUseHostnameForLocalRequests()) {
relativeUrls = RelativeUrlsUsed.BROWSER_ONLY;
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
serverBuilder.host(UriUtils.getHostName()).port(config.getLocalRequestsPort()).scheme(config.getLocalRequestsScheme());
resolveNonBrowserUrls(serverBuilder);
} else {
relativeUrls = RelativeUrlsUsed.ALL_REQUESTS;
return;
}
} else {
// We have absolute URI in config
relativeUrls = RelativeUrlsUsed.NEVER;
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
resolveBrowserUrls(serverBuilder);
resolveNonBrowserUrls(serverBuilder);
}
}
/**
* @param authUrlBuilder absolute URI
*/
protected void resolveBrowserUrls(KeycloakUriBuilder authUrlBuilder) {
if (log.isDebugEnabled()) {
log.debug("resolveBrowserUrls");
}
relativeUrls = false;
serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
String login = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGIN_PATH).build(getRealm()).toString();
String login = authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGIN_PATH).build(getRealm()).toString();
authUrl = KeycloakUriBuilder.fromUri(login);
refreshUrl = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_REFRESH_PATH).build(getRealm()).toString();
logoutUrl = KeycloakUriBuilder.fromUri(serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH).build(getRealm()).toString());
accountUrl = serverBuilder.clone().path(ServiceUrlConstants.ACCOUNT_SERVICE_PATH).build(getRealm()).toString();
realmInfoUrl = serverBuilder.clone().path(ServiceUrlConstants.REALM_INFO_PATH).build(getRealm()).toString();
codeUrl = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_ACCESS_CODE_PATH).build(getRealm()).toString();
}
/**
* @param authUrlBuilder absolute URI
*/
protected void resolveNonBrowserUrls(KeycloakUriBuilder authUrlBuilder) {
if (log.isDebugEnabled()) {
log.debug("resolveNonBrowserUrls");
}
refreshUrl = authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_REFRESH_PATH).build(getRealm()).toString();
logoutUrl = KeycloakUriBuilder.fromUri(authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH).build(getRealm()).toString());
accountUrl = authUrlBuilder.clone().path(ServiceUrlConstants.ACCOUNT_SERVICE_PATH).build(getRealm()).toString();
realmInfoUrl = authUrlBuilder.clone().path(ServiceUrlConstants.REALM_INFO_PATH).build(getRealm()).toString();
codeUrl = authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_ACCESS_CODE_PATH).build(getRealm()).toString();
}
public RelativeUrlsUsed getRelativeUrls() {
return relativeUrls;
}
public String getRealmInfoUrl() {
@@ -2,6 +2,7 @@ package org.keycloak.adapters;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.jboss.logging.Logger;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.util.PemUtils;
@@ -15,6 +16,9 @@ import java.security.PublicKey;
* @version $Revision: 1 $
*/
public class KeycloakDeploymentBuilder {
private static final Logger log = Logger.getLogger(KeycloakDeploymentBuilder.class);
protected KeycloakDeployment deployment = new KeycloakDeployment();
protected KeycloakDeploymentBuilder() {
@@ -68,7 +72,9 @@ public class KeycloakDeploymentBuilder {
if (adapterConfig.getAuthServerUrl() == null && (!deployment.isBearerOnly() || realmKeyPem == null)) {
throw new RuntimeException("You must specify auth-url");
}
deployment.setAuthServerBaseUrl(adapterConfig.getAuthServerUrl());
deployment.setAuthServerBaseUrl(adapterConfig.getAuthServerUrl(), adapterConfig);
log.debug("Use authServerUrl: " + deployment.getAuthServerBaseUrl() + ", codeUrl: " + deployment.getCodeUrl() + ", relativeUrls: " + deployment.getRelativeUrls());
return deployment;
}