keycloak-aplcache
Changes
examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java 9(+7 -2)
examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java 18(+14 -4)
examples/demo-template/product-app/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java 8(+2 -6)
examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java 21(+16 -5)
examples/demo-template/third-party-cdi/src/main/java/org/keycloak/example/oauth/DatabaseClient.java 16(+13 -3)
integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java 58(+54 -4)
integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java 8(+7 -1)
integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java 14(+7 -7)
Details
diff --git a/core/src/main/java/org/keycloak/AbstractOAuthClient.java b/core/src/main/java/org/keycloak/AbstractOAuthClient.java
index 600dab0..00fa0ed 100755
--- a/core/src/main/java/org/keycloak/AbstractOAuthClient.java
+++ b/core/src/main/java/org/keycloak/AbstractOAuthClient.java
@@ -1,5 +1,6 @@
package org.keycloak;
+import org.keycloak.enums.RelativeUrlsUsed;
import org.keycloak.util.KeycloakUriBuilder;
import java.util.Map;
@@ -19,7 +20,7 @@ public class AbstractOAuthClient {
protected String authUrl;
protected String codeUrl;
protected String refreshUrl;
- protected boolean relativeUrls;
+ protected RelativeUrlsUsed relativeUrlsUsed;
protected String scope;
protected String stateCookieName = OAUTH_TOKEN_REQUEST_STATE;
protected String stateCookiePath;
@@ -101,12 +102,12 @@ public class AbstractOAuthClient {
this.publicClient = publicClient;
}
- public boolean isRelativeUrls() {
- return relativeUrls;
+ public RelativeUrlsUsed getRelativeUrlsUsed() {
+ return relativeUrlsUsed;
}
- public void setRelativeUrls(boolean relativeUrls) {
- this.relativeUrls = relativeUrls;
+ public void setRelativeUrlsUsed(RelativeUrlsUsed relativeUrlsUsed) {
+ this.relativeUrlsUsed = relativeUrlsUsed;
}
protected String stripOauthParametersFromRedirect(String uri) {
diff --git a/core/src/main/java/org/keycloak/enums/RelativeUrlsUsed.java b/core/src/main/java/org/keycloak/enums/RelativeUrlsUsed.java
new file mode 100644
index 0000000..cadeb14
--- /dev/null
+++ b/core/src/main/java/org/keycloak/enums/RelativeUrlsUsed.java
@@ -0,0 +1,36 @@
+package org.keycloak.enums;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public enum RelativeUrlsUsed {
+
+ /**
+ * Always use relative URI and resolve them later based on browser HTTP request
+ */
+ ALL_REQUESTS,
+
+ /**
+ * Use relative Uris just for browser requests and resolve those based on browser HTTP requests.
+ * Backend request (like refresh token request, codeToToken request etc) will use the URI based on current hostname
+ */
+ BROWSER_ONLY,
+
+ /**
+ * Relative Uri not used. Configuration contains absolute URI
+ */
+ NEVER;
+
+ public boolean useRelative(boolean isBrowserReq) {
+ switch (this) {
+ case ALL_REQUESTS:
+ return true;
+ case NEVER:
+ return false;
+ case BROWSER_ONLY:
+ return isBrowserReq;
+ default:
+ return true;
+ }
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java b/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java
index 39552b2..acb4243 100755
--- a/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java
+++ b/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java
@@ -16,7 +16,8 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
"expose-token", "bearer-only",
"connection-pool-size",
"allow-any-hostname", "disable-trust-manager", "truststore", "truststore-password",
- "client-keystore", "client-keystore-password", "client-key-password"
+ "client-keystore", "client-keystore-password", "client-key-password",
+ "use-hostname-for-local-requests", "local-requests-scheme", "local-requests-port"
})
public class AdapterConfig extends BaseAdapterConfig {
@@ -36,6 +37,12 @@ public class AdapterConfig extends BaseAdapterConfig {
protected String clientKeyPassword;
@JsonProperty("connection-pool-size")
protected int connectionPoolSize = 20;
+ @JsonProperty("use-hostname-for-local-requests")
+ protected boolean useHostnameForLocalRequests;
+ @JsonProperty("local-requests-scheme")
+ protected String localRequestsScheme = "http";
+ @JsonProperty("local-requests-port")
+ protected int localRequestsPort = 8080;
public boolean isAllowAnyHostname() {
return allowAnyHostname;
@@ -101,4 +108,27 @@ public class AdapterConfig extends BaseAdapterConfig {
this.connectionPoolSize = connectionPoolSize;
}
+ public boolean isUseHostnameForLocalRequests() {
+ return useHostnameForLocalRequests;
+ }
+
+ public void setUseHostnameForLocalRequests(boolean useHostnameForLocalRequests) {
+ this.useHostnameForLocalRequests = useHostnameForLocalRequests;
+ }
+
+ public String getLocalRequestsScheme() {
+ return localRequestsScheme;
+ }
+
+ public void setLocalRequestsScheme(String localRequestsScheme) {
+ this.localRequestsScheme = localRequestsScheme;
+ }
+
+ public int getLocalRequestsPort() {
+ return localRequestsPort;
+ }
+
+ public void setLocalRequestsPort(int localRequestsPort) {
+ this.localRequestsPort = localRequestsPort;
+ }
}
diff --git a/core/src/main/java/org/keycloak/util/UriUtils.java b/core/src/main/java/org/keycloak/util/UriUtils.java
index 873283f..60418ea 100644
--- a/core/src/main/java/org/keycloak/util/UriUtils.java
+++ b/core/src/main/java/org/keycloak/util/UriUtils.java
@@ -1,6 +1,8 @@
package org.keycloak.util;
+import java.net.InetAddress;
import java.net.URI;
+import java.net.UnknownHostException;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -16,4 +18,12 @@ public class UriUtils {
return u.substring(0, u.indexOf('/', 8));
}
+ public static String getHostName() {
+ try {
+ return InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException uhe) {
+ throw new IllegalStateException(uhe);
+ }
+ }
+
}
diff --git a/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java b/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java
index d97e285..2a83775 100755
--- a/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java
+++ b/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java
@@ -15,6 +15,7 @@ import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.KeycloakUriBuilder;
+import org.keycloak.util.UriUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
@@ -158,8 +159,12 @@ public class AdminClient {
}
public static String getBaseUrl(HttpServletRequest request) {
- String url = request.getRequestURL().toString();
- return url.substring(0, url.indexOf('/', 8));
+ String useHostname = request.getServletContext().getInitParameter("useHostname");
+ if (useHostname != null && "true".equalsIgnoreCase(useHostname)) {
+ return "http://" + UriUtils.getHostName() + ":8080";
+ } else {
+ return UriUtils.getOrigin(request.getRequestURL().toString());
+ }
}
}
diff --git a/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/web.xml b/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/web.xml
index 1c496ce..89fe10e 100755
--- a/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/web.xml
+++ b/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/web.xml
@@ -6,4 +6,9 @@
<module-name>admin-access</module-name>
+ <context-param>
+ <param-name>useHostname</param-name>
+ <param-value>false</param-value>
+ </context-param>
+
</web-app>
diff --git a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/AdminClient.java b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/AdminClient.java
index 0e14f29..611292b 100755
--- a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/AdminClient.java
+++ b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/AdminClient.java
@@ -5,6 +5,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.adapters.AdapterUtils;
import org.keycloak.adapters.HttpClientBuilder;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.util.JsonSerialization;
@@ -42,7 +43,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(AdapterUtils.getBaseUrl(req.getRequestURL().toString(), session) + "/auth/admin/realms/demo/roles");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
@@ -64,9 +65,4 @@ public class AdminClient {
}
}
- public static String getBaseUrl(HttpServletRequest request) {
- String url = request.getRequestURL().toString();
- return url.substring(0, url.indexOf('/', 8));
- }
-
}
diff --git a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
index 83e6c7e..7e3d74c 100755
--- a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
+++ b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
@@ -5,11 +5,18 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.adapters.AdapterUtils;
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 javax.servlet.http.HttpSession;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -48,7 +55,7 @@ public class CustomerDatabaseClient {
HttpClient client = new HttpClientBuilder()
.disableTrustManager().build();
try {
- HttpGet get = new HttpGet(getBaseUrl(req) + "/database/customers");
+ HttpGet get = new HttpGet(AdapterUtils.getBaseUrl(req.getRequestURL().toString(), session) + "/database/customers");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
@@ -70,8 +77,11 @@ public class CustomerDatabaseClient {
}
}
- public static String getBaseUrl(HttpServletRequest request) {
- String url = request.getRequestURL().toString();
- return url.substring(0, url.indexOf('/', 8));
+ public static String increaseAndGetCounter(HttpServletRequest req) {
+ HttpSession session = req.getSession();
+ Integer counter = (Integer)session.getAttribute("counter");
+ counter = (counter == null) ? 1 : counter + 1;
+ session.setAttribute("counter", counter);
+ return String.valueOf(counter);
}
}
diff --git a/examples/demo-template/customer-app/src/main/webapp/customers/session.jsp b/examples/demo-template/customer-app/src/main/webapp/customers/session.jsp
new file mode 100644
index 0000000..07f99a1
--- /dev/null
+++ b/examples/demo-template/customer-app/src/main/webapp/customers/session.jsp
@@ -0,0 +1,17 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1" %>
+<%@ page import="org.keycloak.ServiceUrlConstants" %>
+<%@ page import="org.keycloak.example.CustomerDatabaseClient" %>
+<%@ page import="org.keycloak.representations.IDToken" %>
+<%@ page import="org.keycloak.util.UriUtils" %>
+<html>
+ <head>
+ <title>Customer Session Page</title>
+ </head>
+ <body bgcolor="#E3F6CE">
+ <p>Your hostname: <%= UriUtils.getHostName() %></p>
+ <p>Your session ID: <%= request.getSession().getId() %></p>
+ <p>You visited this page <b><%= CustomerDatabaseClient.increaseAndGetCounter(request) %></b> times.</p>
+ <br><br>
+ </body>
+</html>
\ No newline at end of file
diff --git a/examples/demo-template/customer-app/src/main/webapp/index.html b/examples/demo-template/customer-app/src/main/webapp/index.html
index 1da03e4..8eb0c32 100755
--- a/examples/demo-template/customer-app/src/main/webapp/index.html
+++ b/examples/demo-template/customer-app/src/main/webapp/index.html
@@ -11,5 +11,8 @@
<p><a href="admin/admin.jsp">Customer Admin Interface</a></p>
+<p><a href="customers/session.jsp">Customer Session</a></p>
+
+
</body>
</html>
\ No newline at end of file
diff --git a/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json
index c2241b3..ca0707e 100755
--- a/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json
@@ -7,5 +7,6 @@
"expose-token": true,
"credentials": {
"secret": "password"
- }
+ },
+ "use-hostname-for-local-requests": false
}
diff --git a/examples/demo-template/product-app/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java b/examples/demo-template/product-app/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
index 79827b3..9557f28 100755
--- a/examples/demo-template/product-app/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
+++ b/examples/demo-template/product-app/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
@@ -5,6 +5,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.adapters.AdapterUtils;
import org.keycloak.adapters.HttpClientBuilder;
import org.keycloak.util.JsonSerialization;
@@ -39,7 +40,7 @@ public class ProductDatabaseClient
HttpClient client = new HttpClientBuilder()
.disableTrustManager().build();
try {
- HttpGet get = new HttpGet(getBaseUrl(req) + "/database/products");
+ HttpGet get = new HttpGet(AdapterUtils.getBaseUrl(req.getRequestURL().toString(), session) + "/database/products");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
@@ -61,9 +62,4 @@ public class ProductDatabaseClient
}
}
- public static String getBaseUrl(HttpServletRequest request) {
- String url = request.getRequestURL().toString();
- return url.substring(0, url.indexOf('/', 8));
- }
-
}
diff --git a/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json
index fb07e7f..c1ae517 100755
--- a/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json
@@ -6,5 +6,6 @@
"ssl-required" : "external",
"credentials" : {
"secret": "password"
- }
+ },
+ "use-hostname-for-local-requests": false
}
diff --git a/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java b/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
index d9377c9..a12bcee 100755
--- a/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
+++ b/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
@@ -5,9 +5,11 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.adapters.ServerRequest;
+import org.keycloak.enums.RelativeUrlsUsed;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.servlet.ServletOAuthClient;
import org.keycloak.util.JsonSerialization;
+import org.keycloak.util.UriUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -58,7 +60,6 @@ public class ProductDatabaseClient {
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
// and take a look how it works. You can also take a look at third-party-cdi example
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
- String token = null;
try {
return oAuthClient.getBearerToken(request);
} catch (IOException e) {
@@ -78,7 +79,7 @@ public class ProductDatabaseClient {
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
HttpClient client = oAuthClient.getClient();
- HttpGet get = new HttpGet(getBaseUrl(request) + "/database/products");
+ HttpGet get = new HttpGet(getBaseUrl(oAuthClient, request) + "/database/products");
get.addHeader("Authorization", "Bearer " + accessToken);
try {
HttpResponse response = client.execute(get);
@@ -97,9 +98,19 @@ public class ProductDatabaseClient {
}
}
- public static String getBaseUrl(HttpServletRequest request) {
- String url = request.getRequestURL().toString();
- return url.substring(0, url.indexOf('/', 8));
+ public static String getBaseUrl(ServletOAuthClient oAuthClient, HttpServletRequest request) {
+ switch (oAuthClient.getRelativeUrlsUsed()) {
+ 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(oAuthClient.getCodeUrl());
+ case NEVER:
+ return "";
+ default:
+ return "";
+ }
}
}
diff --git a/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json
index 559df05..14bbd79 100755
--- a/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json
@@ -5,5 +5,6 @@
"ssl-required" : "external",
"credentials" : {
"secret": "password"
- }
+ },
+ "use-hostname-for-local-requests": false
}
\ No newline at end of file
diff --git a/examples/demo-template/third-party-cdi/src/main/java/org/keycloak/example/oauth/DatabaseClient.java b/examples/demo-template/third-party-cdi/src/main/java/org/keycloak/example/oauth/DatabaseClient.java
index d76c55c..e642605 100755
--- a/examples/demo-template/third-party-cdi/src/main/java/org/keycloak/example/oauth/DatabaseClient.java
+++ b/examples/demo-template/third-party-cdi/src/main/java/org/keycloak/example/oauth/DatabaseClient.java
@@ -7,6 +7,7 @@ import org.apache.http.client.methods.HttpGet;
import org.jboss.logging.Logger;
import org.keycloak.servlet.ServletOAuthClient;
import org.keycloak.util.JsonSerialization;
+import org.keycloak.util.UriUtils;
import javax.enterprise.context.ApplicationScoped;
import javax.faces.application.FacesMessage;
@@ -102,9 +103,18 @@ public class DatabaseClient {
}
public String getBaseUrl() {
- String url = request.getRequestURL().toString();
- return url.substring(0, url.indexOf('/', 8));
+ switch (oauthClient.getRelativeUrlsUsed()) {
+ 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(oauthClient.getCodeUrl());
+ case NEVER:
+ return "";
+ default:
+ return "";
+ }
}
-
}
diff --git a/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json
index 559df05..14bbd79 100755
--- a/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json
@@ -5,5 +5,6 @@
"ssl-required" : "external",
"credentials" : {
"secret": "password"
- }
+ },
+ "use-hostname-for-local-requests": false
}
\ No newline at end of file
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java
index 676fcae..f1e5292 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java
@@ -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();
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterUtils.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterUtils.java
new file mode 100644
index 0000000..0048d6a
--- /dev/null
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterUtils.java
@@ -0,0 +1,30 @@
+package org.keycloak.adapters;
+
+import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.util.UriUtils;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class AdapterUtils {
+
+ public static String getBaseUrl(String browserRequestURL, 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(browserRequestURL);
+ 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(browserRequestURL);
+ }
+ }
+}
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
index 053dddf..9709294 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
@@ -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);
}
+ }
+
- relativeUrls = false;
- serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
- String login = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGIN_PATH).build(getRealm()).toString();
+ /**
+ * @param authUrlBuilder absolute URI
+ */
+ protected void resolveBrowserUrls(KeycloakUriBuilder authUrlBuilder) {
+ if (log.isDebugEnabled()) {
+ log.debug("resolveBrowserUrls");
+ }
+
+ 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() {
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java
index 963519b..0a3ab33 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java
@@ -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;
}
diff --git a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
index 34e8035..0e414ec 100755
--- a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
+++ b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
@@ -8,6 +8,7 @@ import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.IDToken;
import org.keycloak.util.KeycloakUriBuilder;
+import org.keycloak.util.UriUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@@ -40,7 +41,7 @@ public class ServletOAuthClient extends AbstractOAuthClient {
}
private AccessTokenResponse resolveBearerToken(HttpServletRequest request, String redirectUri, String code) throws IOException, ServerRequest.HttpFailure {
- return ServerRequest.invokeAccessCodeToToken(client, publicClient, code, getUrl(request, codeUrl), redirectUri, clientId, credentials);
+ return ServerRequest.invokeAccessCodeToToken(client, publicClient, code, getUrl(request, codeUrl, false), redirectUri, clientId, credentials);
}
/**
@@ -74,7 +75,7 @@ public class ServletOAuthClient extends AbstractOAuthClient {
public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException {
String state = getStateCode();
- KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(getUrl(request, authUrl))
+ KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(getUrl(request, authUrl, true))
.queryParam(OAuth2Constants.CLIENT_ID, clientId)
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
.queryParam(OAuth2Constants.STATE, state);
@@ -146,7 +147,7 @@ public class ServletOAuthClient extends AbstractOAuthClient {
}
public AccessTokenResponse refreshToken(HttpServletRequest request, String refreshToken) throws IOException, ServerRequest.HttpFailure {
- return ServerRequest.invokeRefresh(client, publicClient, refreshToken, getUrl(request, refreshUrl), clientId, credentials);
+ return ServerRequest.invokeRefresh(client, publicClient, refreshToken, getUrl(request, refreshUrl, false), clientId, credentials);
}
public static IDToken extractIdToken(String idToken) {
@@ -159,10 +160,9 @@ public class ServletOAuthClient extends AbstractOAuthClient {
}
}
- private String getUrl(HttpServletRequest request, String url) {
- if (relativeUrls) {
- String baseUrl = request.getRequestURL().toString();
- baseUrl = baseUrl.substring(0, baseUrl.indexOf('/', 8));
+ private String getUrl(HttpServletRequest request, String url, boolean isBrowserRequest) {
+ if (relativeUrlsUsed.useRelative(isBrowserRequest)) {
+ String baseUrl = UriUtils.getOrigin(request.getRequestURL().toString());
return baseUrl + url;
} else {
return url;
diff --git a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java
index 52d9710..e1ccd5d 100755
--- a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java
+++ b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java
@@ -3,9 +3,11 @@ package org.keycloak.servlet;
import org.apache.http.client.HttpClient;
import org.keycloak.ServiceUrlConstants;
import org.keycloak.adapters.HttpClientBuilder;
+import org.keycloak.enums.RelativeUrlsUsed;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.KeycloakUriBuilder;
+import org.keycloak.util.UriUtils;
import java.io.IOException;
import java.io.InputStream;
@@ -21,7 +23,7 @@ public class ServletOAuthClientBuilder {
return build(adapterConfig);
}
- private static AdapterConfig getAdapterConfig(InputStream is) {
+ public static AdapterConfig getAdapterConfig(InputStream is) {
try {
return JsonSerialization.readValue(is, AdapterConfig.class);
} catch (IOException e) {
@@ -50,13 +52,31 @@ public class ServletOAuthClientBuilder {
throw new RuntimeException("You must specify auth-url");
}
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(adapterConfig.getAuthServerUrl());
- oauthClient.setRelativeUrls(serverBuilder.clone().getHost() == null);
+ RelativeUrlsUsed useRelative = relativeUrls(serverBuilder, adapterConfig);
+ oauthClient.setRelativeUrlsUsed(useRelative);
String authUrl = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGIN_PATH).build(adapterConfig.getRealm()).toString();
- String tokenUrl = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_ACCESS_CODE_PATH).build(adapterConfig.getRealm()).toString();
- String refreshUrl = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_REFRESH_PATH).build(adapterConfig.getRealm()).toString();
+
+ KeycloakUriBuilder tokenUrlBuilder = serverBuilder.clone();
+ KeycloakUriBuilder refreshUrlBuilder = serverBuilder.clone();
+
+ if (useRelative == RelativeUrlsUsed.BROWSER_ONLY) {
+ // Use absolute URI for refreshToken and codeToToken requests
+ tokenUrlBuilder.scheme(adapterConfig.getLocalRequestsScheme()).host(UriUtils.getHostName()).port(adapterConfig.getLocalRequestsPort());
+ refreshUrlBuilder.scheme(adapterConfig.getLocalRequestsScheme()).host(UriUtils.getHostName()).port(adapterConfig.getLocalRequestsPort());
+ }
+ String tokenUrl = tokenUrlBuilder.path(ServiceUrlConstants.TOKEN_SERVICE_ACCESS_CODE_PATH).build(adapterConfig.getRealm()).toString();
+ String refreshUrl = refreshUrlBuilder.path(ServiceUrlConstants.TOKEN_SERVICE_REFRESH_PATH).build(adapterConfig.getRealm()).toString();
oauthClient.setAuthUrl(authUrl);
oauthClient.setCodeUrl(tokenUrl);
oauthClient.setRefreshUrl(refreshUrl);
}
+
+ private static RelativeUrlsUsed relativeUrls(KeycloakUriBuilder serverBuilder, AdapterConfig adapterConfig) {
+ if (serverBuilder.clone().getHost() == null) {
+ return (adapterConfig.isUseHostnameForLocalRequests()) ? RelativeUrlsUsed.BROWSER_ONLY : RelativeUrlsUsed.ALL_REQUESTS;
+ } else {
+ return RelativeUrlsUsed.NEVER;
+ }
+ }
}
diff --git a/testsuite/docker-cluster/wildfly/deploy-examples.sh b/testsuite/docker-cluster/wildfly/deploy-examples.sh
new file mode 100644
index 0000000..d102dc2
--- /dev/null
+++ b/testsuite/docker-cluster/wildfly/deploy-examples.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Deploy and configure all examples
+
+# Deploy examples
+cd /keycloak-docker-cluster/examples
+for I in $(find . | grep .war$); do cp $I /opt/wildfly/standalone/deployments/; done;
+
+# Explode wars
+cd /opt/wildfly/standalone/deployments/
+for I in $(ls -d *.war | grep -v auth-server.war); do
+ echo "Explode dir $I";
+ mkdir $I.tmp;
+ cd $I.tmp;
+ unzip -q ../$I;
+ cd ..
+ rm $I;
+ mv $I.tmp $I;
+ touch $I.dodeploy;
+done;
+
+
+# Configure admin-access.war
+sed -i -e 's/false/true/' admin-access.war/WEB-INF/web.xml
+
+# Configure other examples
+for I in *.war/WEB-INF/keycloak.json; do
+ echo "Configuring $I";
+ sed -i -e 's/\"use-hostname-for-local-requests\": false/\"use-hostname-for-local-requests\": true/' $I;
+done;
+
+
diff --git a/testsuite/docker-cluster/wildfly/Dockerfile b/testsuite/docker-cluster/wildfly/Dockerfile
index 3727d5b..3fde5bc 100644
--- a/testsuite/docker-cluster/wildfly/Dockerfile
+++ b/testsuite/docker-cluster/wildfly/Dockerfile
@@ -29,6 +29,8 @@ RUN sed -i "s|#JAVA_OPTS=\"\$JAVA_OPTS -agentlib:jdwp=transport=dt_socket|JAVA_O
ADD mysql-keycloak-ds.xml /opt/wildfly/standalone/deployments/
ADD keycloak-run-node.sh /keycloak-run-node.sh
RUN chmod u+x /keycloak-run-node.sh
+ADD deploy-examples.sh /deploy-examples.sh
+RUN chmod u+x /deploy-examples.sh
EXPOSE 8787
diff --git a/testsuite/docker-cluster/wildfly/keycloak-run-node.sh b/testsuite/docker-cluster/wildfly/keycloak-run-node.sh
index b9af405..40603f9 100644
--- a/testsuite/docker-cluster/wildfly/keycloak-run-node.sh
+++ b/testsuite/docker-cluster/wildfly/keycloak-run-node.sh
@@ -50,9 +50,8 @@ cp -r /keycloak-docker-cluster/modules ./
# Deploy keycloak
cp -r /keycloak-docker-cluster/deployments/* /opt/wildfly/standalone/deployments/
-# Deploy examples
-cd /keycloak-docker-cluster/examples
-for I in $(find . | grep .war$); do cp $I /opt/wildfly/standalone/deployments/; done;
+# Deploy and configure examples
+/deploy-examples.sh
# Deploy to volume
rm -rf /keycloak-docker-shared/keycloak-wildfly-$MYHOST