Merge pull request #719 from mposolda/master
KEYCLOAK-721 Possibility to resolve relative URI by hostname. Examples working in docker clustering env
This commit is contained in:
commit
72ec9ccb00
26 changed files with 383 additions and 69 deletions
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak;
|
package org.keycloak;
|
||||||
|
|
||||||
|
import org.keycloak.enums.RelativeUrlsUsed;
|
||||||
import org.keycloak.util.KeycloakUriBuilder;
|
import org.keycloak.util.KeycloakUriBuilder;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -19,7 +20,7 @@ public class AbstractOAuthClient {
|
||||||
protected String authUrl;
|
protected String authUrl;
|
||||||
protected String codeUrl;
|
protected String codeUrl;
|
||||||
protected String refreshUrl;
|
protected String refreshUrl;
|
||||||
protected boolean relativeUrls;
|
protected RelativeUrlsUsed relativeUrlsUsed;
|
||||||
protected String scope;
|
protected String scope;
|
||||||
protected String stateCookieName = OAUTH_TOKEN_REQUEST_STATE;
|
protected String stateCookieName = OAUTH_TOKEN_REQUEST_STATE;
|
||||||
protected String stateCookiePath;
|
protected String stateCookiePath;
|
||||||
|
@ -101,12 +102,12 @@ public class AbstractOAuthClient {
|
||||||
this.publicClient = publicClient;
|
this.publicClient = publicClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRelativeUrls() {
|
public RelativeUrlsUsed getRelativeUrlsUsed() {
|
||||||
return relativeUrls;
|
return relativeUrlsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRelativeUrls(boolean relativeUrls) {
|
public void setRelativeUrlsUsed(RelativeUrlsUsed relativeUrlsUsed) {
|
||||||
this.relativeUrls = relativeUrls;
|
this.relativeUrlsUsed = relativeUrlsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String stripOauthParametersFromRedirect(String uri) {
|
protected String stripOauthParametersFromRedirect(String uri) {
|
||||||
|
|
36
core/src/main/java/org/keycloak/enums/RelativeUrlsUsed.java
Normal file
36
core/src/main/java/org/keycloak/enums/RelativeUrlsUsed.java
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,8 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
|
||||||
"expose-token", "bearer-only",
|
"expose-token", "bearer-only",
|
||||||
"connection-pool-size",
|
"connection-pool-size",
|
||||||
"allow-any-hostname", "disable-trust-manager", "truststore", "truststore-password",
|
"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 {
|
public class AdapterConfig extends BaseAdapterConfig {
|
||||||
|
|
||||||
|
@ -36,6 +37,12 @@ public class AdapterConfig extends BaseAdapterConfig {
|
||||||
protected String clientKeyPassword;
|
protected String clientKeyPassword;
|
||||||
@JsonProperty("connection-pool-size")
|
@JsonProperty("connection-pool-size")
|
||||||
protected int connectionPoolSize = 20;
|
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() {
|
public boolean isAllowAnyHostname() {
|
||||||
return allowAnyHostname;
|
return allowAnyHostname;
|
||||||
|
@ -101,4 +108,27 @@ public class AdapterConfig extends BaseAdapterConfig {
|
||||||
this.connectionPoolSize = connectionPoolSize;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package org.keycloak.util;
|
package org.keycloak.util;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -16,4 +18,12 @@ public class UriUtils {
|
||||||
return u.substring(0, u.indexOf('/', 8));
|
return u.substring(0, u.indexOf('/', 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getHostName() {
|
||||||
|
try {
|
||||||
|
return InetAddress.getLocalHost().getHostName();
|
||||||
|
} catch (UnknownHostException uhe) {
|
||||||
|
throw new IllegalStateException(uhe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.keycloak.representations.AccessTokenResponse;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.util.KeycloakUriBuilder;
|
import org.keycloak.util.KeycloakUriBuilder;
|
||||||
|
import org.keycloak.util.UriUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
@ -158,8 +159,12 @@ public class AdminClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBaseUrl(HttpServletRequest request) {
|
public static String getBaseUrl(HttpServletRequest request) {
|
||||||
String url = request.getRequestURL().toString();
|
String useHostname = request.getServletContext().getInitParameter("useHostname");
|
||||||
return url.substring(0, url.indexOf('/', 8));
|
if (useHostname != null && "true".equalsIgnoreCase(useHostname)) {
|
||||||
|
return "http://" + UriUtils.getHostName() + ":8080";
|
||||||
|
} else {
|
||||||
|
return UriUtils.getOrigin(request.getRequestURL().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,9 @@
|
||||||
|
|
||||||
<module-name>admin-access</module-name>
|
<module-name>admin-access</module-name>
|
||||||
|
|
||||||
|
<context-param>
|
||||||
|
<param-name>useHostname</param-name>
|
||||||
|
<param-value>false</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
</web-app>
|
</web-app>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.keycloak.KeycloakSecurityContext;
|
import org.keycloak.KeycloakSecurityContext;
|
||||||
|
import org.keycloak.adapters.AdapterUtils;
|
||||||
import org.keycloak.adapters.HttpClientBuilder;
|
import org.keycloak.adapters.HttpClientBuilder;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
@ -42,7 +43,7 @@ public class AdminClient {
|
||||||
HttpClient client = new HttpClientBuilder()
|
HttpClient client = new HttpClientBuilder()
|
||||||
.disableTrustManager().build();
|
.disableTrustManager().build();
|
||||||
try {
|
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());
|
get.addHeader("Authorization", "Bearer " + session.getTokenString());
|
||||||
try {
|
try {
|
||||||
HttpResponse response = client.execute(get);
|
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,18 @@ import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.keycloak.KeycloakSecurityContext;
|
import org.keycloak.KeycloakSecurityContext;
|
||||||
|
import org.keycloak.adapters.AdapterUtils;
|
||||||
import org.keycloak.adapters.HttpClientBuilder;
|
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.representations.IDToken;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
import org.keycloak.util.UriUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -48,7 +55,7 @@ public class CustomerDatabaseClient {
|
||||||
HttpClient client = new HttpClientBuilder()
|
HttpClient client = new HttpClientBuilder()
|
||||||
.disableTrustManager().build();
|
.disableTrustManager().build();
|
||||||
try {
|
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());
|
get.addHeader("Authorization", "Bearer " + session.getTokenString());
|
||||||
try {
|
try {
|
||||||
HttpResponse response = client.execute(get);
|
HttpResponse response = client.execute(get);
|
||||||
|
@ -70,8 +77,11 @@ public class CustomerDatabaseClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBaseUrl(HttpServletRequest request) {
|
public static String increaseAndGetCounter(HttpServletRequest req) {
|
||||||
String url = request.getRequestURL().toString();
|
HttpSession session = req.getSession();
|
||||||
return url.substring(0, url.indexOf('/', 8));
|
Integer counter = (Integer)session.getAttribute("counter");
|
||||||
|
counter = (counter == null) ? 1 : counter + 1;
|
||||||
|
session.setAttribute("counter", counter);
|
||||||
|
return String.valueOf(counter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,6 @@
|
||||||
"expose-token": true,
|
"expose-token": true,
|
||||||
"credentials": {
|
"credentials": {
|
||||||
"secret": "password"
|
"secret": "password"
|
||||||
}
|
},
|
||||||
|
"use-hostname-for-local-requests": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -11,5 +11,8 @@
|
||||||
|
|
||||||
<p><a href="admin/admin.jsp">Customer Admin Interface</a></p>
|
<p><a href="admin/admin.jsp">Customer Admin Interface</a></p>
|
||||||
|
|
||||||
|
<p><a href="customers/session.jsp">Customer Session</a></p>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -5,6 +5,7 @@ import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.keycloak.KeycloakSecurityContext;
|
import org.keycloak.KeycloakSecurityContext;
|
||||||
|
import org.keycloak.adapters.AdapterUtils;
|
||||||
import org.keycloak.adapters.HttpClientBuilder;
|
import org.keycloak.adapters.HttpClientBuilder;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ public class ProductDatabaseClient
|
||||||
HttpClient client = new HttpClientBuilder()
|
HttpClient client = new HttpClientBuilder()
|
||||||
.disableTrustManager().build();
|
.disableTrustManager().build();
|
||||||
try {
|
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());
|
get.addHeader("Authorization", "Bearer " + session.getTokenString());
|
||||||
try {
|
try {
|
||||||
HttpResponse response = client.execute(get);
|
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,6 @@
|
||||||
"ssl-required" : "external",
|
"ssl-required" : "external",
|
||||||
"credentials" : {
|
"credentials" : {
|
||||||
"secret": "password"
|
"secret": "password"
|
||||||
}
|
},
|
||||||
|
"use-hostname-for-local-requests": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.apache.http.client.methods.HttpGet;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.servlet.ServletOAuthClient;
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
import org.keycloak.util.UriUtils;
|
||||||
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.faces.application.FacesMessage;
|
import javax.faces.application.FacesMessage;
|
||||||
|
@ -102,9 +103,18 @@ public class DatabaseClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBaseUrl() {
|
public String getBaseUrl() {
|
||||||
String url = request.getRequestURL().toString();
|
switch (oauthClient.getRelativeUrlsUsed()) {
|
||||||
return url.substring(0, url.indexOf('/', 8));
|
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 "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
"ssl-required" : "external",
|
"ssl-required" : "external",
|
||||||
"credentials" : {
|
"credentials" : {
|
||||||
"secret": "password"
|
"secret": "password"
|
||||||
}
|
},
|
||||||
|
"use-hostname-for-local-requests": false
|
||||||
}
|
}
|
|
@ -5,9 +5,11 @@ import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.keycloak.adapters.ServerRequest;
|
import org.keycloak.adapters.ServerRequest;
|
||||||
|
import org.keycloak.enums.RelativeUrlsUsed;
|
||||||
import org.keycloak.representations.AccessTokenResponse;
|
import org.keycloak.representations.AccessTokenResponse;
|
||||||
import org.keycloak.servlet.ServletOAuthClient;
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
import org.keycloak.util.UriUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -58,7 +60,6 @@ public class ProductDatabaseClient {
|
||||||
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
// 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
|
// 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());
|
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
||||||
String token = null;
|
|
||||||
try {
|
try {
|
||||||
return oAuthClient.getBearerToken(request);
|
return oAuthClient.getBearerToken(request);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -78,7 +79,7 @@ public class ProductDatabaseClient {
|
||||||
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
||||||
HttpClient client = oAuthClient.getClient();
|
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);
|
get.addHeader("Authorization", "Bearer " + accessToken);
|
||||||
try {
|
try {
|
||||||
HttpResponse response = client.execute(get);
|
HttpResponse response = client.execute(get);
|
||||||
|
@ -97,9 +98,19 @@ public class ProductDatabaseClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBaseUrl(HttpServletRequest request) {
|
public static String getBaseUrl(ServletOAuthClient oAuthClient, HttpServletRequest request) {
|
||||||
String url = request.getRequestURL().toString();
|
switch (oAuthClient.getRelativeUrlsUsed()) {
|
||||||
return url.substring(0, url.indexOf('/', 8));
|
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 "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
"ssl-required" : "external",
|
"ssl-required" : "external",
|
||||||
"credentials" : {
|
"credentials" : {
|
||||||
"secret": "password"
|
"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.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.enums.RelativeUrlsUsed;
|
||||||
import org.keycloak.enums.SslRequired;
|
import org.keycloak.enums.SslRequired;
|
||||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||||
import org.keycloak.representations.idm.PublishedRealmRepresentation;
|
import org.keycloak.representations.idm.PublishedRealmRepresentation;
|
||||||
|
@ -48,14 +49,23 @@ public class AdapterDeploymentContext {
|
||||||
KeycloakDeployment deployment = this.deployment;
|
KeycloakDeployment deployment = this.deployment;
|
||||||
if (deployment == null) return null;
|
if (deployment == null) return null;
|
||||||
if (deployment.getAuthServerBaseUrl() == null) return deployment;
|
if (deployment.getAuthServerBaseUrl() == null) return deployment;
|
||||||
if (deployment.relativeUrls) {
|
|
||||||
deployment = new DeploymentDelegate(this.deployment);
|
deployment = resolveUrls(deployment, facade);
|
||||||
deployment.setAuthServerBaseUrl(getBaseBuilder(facade, this.deployment.getAuthServerBaseUrl()).build().toString());
|
|
||||||
}
|
|
||||||
if (deployment.getRealmKey() == null) resolveRealmKey(deployment);
|
if (deployment.getRealmKey() == null) resolveRealmKey(deployment);
|
||||||
return 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) {
|
protected void resolveRealmKey(KeycloakDeployment deployment) {
|
||||||
if (deployment.getClient() == null) {
|
if (deployment.getClient() == null) {
|
||||||
throw new RuntimeException("KeycloakDeployment was never initialized through appropriate SPIs");
|
throw new RuntimeException("KeycloakDeployment was never initialized through appropriate SPIs");
|
||||||
|
@ -107,6 +117,46 @@ public class AdapterDeploymentContext {
|
||||||
this.delegate = delegate;
|
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
|
@Override
|
||||||
public String getResourceName() {
|
public String getResourceName() {
|
||||||
return delegate.getResourceName();
|
return delegate.getResourceName();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,13 @@
|
||||||
package org.keycloak.adapters;
|
package org.keycloak.adapters;
|
||||||
|
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.ServiceUrlConstants;
|
import org.keycloak.ServiceUrlConstants;
|
||||||
|
import org.keycloak.enums.RelativeUrlsUsed;
|
||||||
import org.keycloak.enums.SslRequired;
|
import org.keycloak.enums.SslRequired;
|
||||||
|
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||||
import org.keycloak.util.KeycloakUriBuilder;
|
import org.keycloak.util.KeycloakUriBuilder;
|
||||||
|
import org.keycloak.util.UriUtils;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
@ -16,10 +20,11 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class KeycloakDeployment {
|
public class KeycloakDeployment {
|
||||||
|
|
||||||
protected boolean relativeUrls;
|
private static final Logger log = Logger.getLogger(KeycloakDeployment.class);
|
||||||
|
|
||||||
|
protected RelativeUrlsUsed relativeUrls;
|
||||||
protected String realm;
|
protected String realm;
|
||||||
protected PublicKey realmKey;
|
protected PublicKey realmKey;
|
||||||
protected KeycloakUriBuilder serverBuilder;
|
|
||||||
protected String authServerBaseUrl;
|
protected String authServerBaseUrl;
|
||||||
protected String realmInfoUrl;
|
protected String realmInfoUrl;
|
||||||
protected KeycloakUriBuilder authUrl;
|
protected KeycloakUriBuilder authUrl;
|
||||||
|
@ -76,26 +81,62 @@ public class KeycloakDeployment {
|
||||||
return authServerBaseUrl;
|
return authServerBaseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthServerBaseUrl(String authServerBaseUrl) {
|
public void setAuthServerBaseUrl(String authServerBaseUrl, AdapterConfig config) {
|
||||||
this.authServerBaseUrl = authServerBaseUrl;
|
this.authServerBaseUrl = authServerBaseUrl;
|
||||||
if (authServerBaseUrl == null) return;
|
if (authServerBaseUrl == null) return;
|
||||||
|
|
||||||
URI uri = URI.create(authServerBaseUrl);
|
URI uri = URI.create(authServerBaseUrl);
|
||||||
if (uri.getHost() == null) {
|
if (uri.getHost() == null) {
|
||||||
relativeUrls = true;
|
if (config.isUseHostnameForLocalRequests()) {
|
||||||
return;
|
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;
|
String login = authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGIN_PATH).build(getRealm()).toString();
|
||||||
|
|
||||||
serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
|
|
||||||
String login = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGIN_PATH).build(getRealm()).toString();
|
|
||||||
authUrl = KeycloakUriBuilder.fromUri(login);
|
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();
|
* @param authUrlBuilder absolute URI
|
||||||
codeUrl = serverBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_ACCESS_CODE_PATH).build(getRealm()).toString();
|
*/
|
||||||
|
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() {
|
public String getRealmInfoUrl() {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.keycloak.adapters;
|
||||||
|
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.enums.SslRequired;
|
import org.keycloak.enums.SslRequired;
|
||||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||||
import org.keycloak.util.PemUtils;
|
import org.keycloak.util.PemUtils;
|
||||||
|
@ -15,6 +16,9 @@ import java.security.PublicKey;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class KeycloakDeploymentBuilder {
|
public class KeycloakDeploymentBuilder {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(KeycloakDeploymentBuilder.class);
|
||||||
|
|
||||||
protected KeycloakDeployment deployment = new KeycloakDeployment();
|
protected KeycloakDeployment deployment = new KeycloakDeployment();
|
||||||
|
|
||||||
protected KeycloakDeploymentBuilder() {
|
protected KeycloakDeploymentBuilder() {
|
||||||
|
@ -68,7 +72,9 @@ public class KeycloakDeploymentBuilder {
|
||||||
if (adapterConfig.getAuthServerUrl() == null && (!deployment.isBearerOnly() || realmKeyPem == null)) {
|
if (adapterConfig.getAuthServerUrl() == null && (!deployment.isBearerOnly() || realmKeyPem == null)) {
|
||||||
throw new RuntimeException("You must specify auth-url");
|
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;
|
return deployment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import org.keycloak.jose.jws.JWSInput;
|
||||||
import org.keycloak.representations.AccessTokenResponse;
|
import org.keycloak.representations.AccessTokenResponse;
|
||||||
import org.keycloak.representations.IDToken;
|
import org.keycloak.representations.IDToken;
|
||||||
import org.keycloak.util.KeycloakUriBuilder;
|
import org.keycloak.util.KeycloakUriBuilder;
|
||||||
|
import org.keycloak.util.UriUtils;
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
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 {
|
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 {
|
public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
String state = getStateCode();
|
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.CLIENT_ID, clientId)
|
||||||
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
|
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
|
||||||
.queryParam(OAuth2Constants.STATE, state);
|
.queryParam(OAuth2Constants.STATE, state);
|
||||||
|
@ -146,7 +147,7 @@ public class ServletOAuthClient extends AbstractOAuthClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccessTokenResponse refreshToken(HttpServletRequest request, String refreshToken) throws IOException, ServerRequest.HttpFailure {
|
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) {
|
public static IDToken extractIdToken(String idToken) {
|
||||||
|
@ -159,10 +160,9 @@ public class ServletOAuthClient extends AbstractOAuthClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUrl(HttpServletRequest request, String url) {
|
private String getUrl(HttpServletRequest request, String url, boolean isBrowserRequest) {
|
||||||
if (relativeUrls) {
|
if (relativeUrlsUsed.useRelative(isBrowserRequest)) {
|
||||||
String baseUrl = request.getRequestURL().toString();
|
String baseUrl = UriUtils.getOrigin(request.getRequestURL().toString());
|
||||||
baseUrl = baseUrl.substring(0, baseUrl.indexOf('/', 8));
|
|
||||||
return baseUrl + url;
|
return baseUrl + url;
|
||||||
} else {
|
} else {
|
||||||
return url;
|
return url;
|
||||||
|
|
|
@ -3,9 +3,11 @@ package org.keycloak.servlet;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.keycloak.ServiceUrlConstants;
|
import org.keycloak.ServiceUrlConstants;
|
||||||
import org.keycloak.adapters.HttpClientBuilder;
|
import org.keycloak.adapters.HttpClientBuilder;
|
||||||
|
import org.keycloak.enums.RelativeUrlsUsed;
|
||||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.util.KeycloakUriBuilder;
|
import org.keycloak.util.KeycloakUriBuilder;
|
||||||
|
import org.keycloak.util.UriUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -21,7 +23,7 @@ public class ServletOAuthClientBuilder {
|
||||||
return build(adapterConfig);
|
return build(adapterConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AdapterConfig getAdapterConfig(InputStream is) {
|
public static AdapterConfig getAdapterConfig(InputStream is) {
|
||||||
try {
|
try {
|
||||||
return JsonSerialization.readValue(is, AdapterConfig.class);
|
return JsonSerialization.readValue(is, AdapterConfig.class);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -50,13 +52,31 @@ public class ServletOAuthClientBuilder {
|
||||||
throw new RuntimeException("You must specify auth-url");
|
throw new RuntimeException("You must specify auth-url");
|
||||||
}
|
}
|
||||||
KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(adapterConfig.getAuthServerUrl());
|
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 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.setAuthUrl(authUrl);
|
||||||
oauthClient.setCodeUrl(tokenUrl);
|
oauthClient.setCodeUrl(tokenUrl);
|
||||||
oauthClient.setRefreshUrl(refreshUrl);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 mysql-keycloak-ds.xml /opt/wildfly/standalone/deployments/
|
||||||
ADD keycloak-run-node.sh /keycloak-run-node.sh
|
ADD keycloak-run-node.sh /keycloak-run-node.sh
|
||||||
RUN chmod u+x /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
|
EXPOSE 8787
|
||||||
|
|
||||||
|
|
32
testsuite/docker-cluster/wildfly/deploy-examples.sh
Normal file
32
testsuite/docker-cluster/wildfly/deploy-examples.sh
Normal file
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,8 @@ cp -r /keycloak-docker-cluster/modules ./
|
||||||
# Deploy keycloak
|
# Deploy keycloak
|
||||||
cp -r /keycloak-docker-cluster/deployments/* /opt/wildfly/standalone/deployments/
|
cp -r /keycloak-docker-cluster/deployments/* /opt/wildfly/standalone/deployments/
|
||||||
|
|
||||||
# Deploy examples
|
# Deploy and configure examples
|
||||||
cd /keycloak-docker-cluster/examples
|
/deploy-examples.sh
|
||||||
for I in $(find . | grep .war$); do cp $I /opt/wildfly/standalone/deployments/; done;
|
|
||||||
|
|
||||||
# Deploy to volume
|
# Deploy to volume
|
||||||
rm -rf /keycloak-docker-shared/keycloak-wildfly-$MYHOST
|
rm -rf /keycloak-docker-shared/keycloak-wildfly-$MYHOST
|
||||||
|
|
Loading…
Reference in a new issue