KEYCLOAK-2054 - Allow to configure proxy for auth-server requests in adapters.
Previously the adapter configuration did not support specifying a proxy for auth-server requests issued via the Apache HTTP Client by Keycloak. This made it very difficult to connect an Application with Keycloak that was required to use a proxy. Introduced new `proxy-url` attribute to the adapter configuration which makes it possible to configure a proxy to be used for auth-server requests. Proxy-Host, Proxy-Port and Proxy-Scheme are taken from the configured proxy URL. Note that proxies that require authentication are currently not supported.
This commit is contained in:
parent
d98cd4235c
commit
bccc5fa7b1
3 changed files with 65 additions and 11 deletions
|
@ -17,9 +17,11 @@
|
|||
|
||||
package org.keycloak.adapters;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.client.CookieStore;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.conn.params.ConnRoutePNames;
|
||||
import org.apache.http.conn.scheme.PlainSocketFactory;
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||
|
@ -34,9 +36,9 @@ import org.apache.http.impl.conn.SingleClientConnManager;
|
|||
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpConnectionParams;
|
||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||
import org.keycloak.common.util.EnvUtil;
|
||||
import org.keycloak.common.util.KeystoreUtil;
|
||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
@ -46,6 +48,7 @@ import javax.net.ssl.SSLSocket;
|
|||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.security.KeyStore;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateException;
|
||||
|
@ -112,6 +115,7 @@ public class HttpClientBuilder {
|
|||
protected TimeUnit socketTimeoutUnits = TimeUnit.MILLISECONDS;
|
||||
protected long establishConnectionTimeout = -1;
|
||||
protected TimeUnit establishConnectionTimeoutUnits = TimeUnit.MILLISECONDS;
|
||||
protected HttpHost proxyHost;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -121,8 +125,7 @@ public class HttpClientBuilder {
|
|||
* @param unit
|
||||
* @return
|
||||
*/
|
||||
public HttpClientBuilder socketTimeout(long timeout, TimeUnit unit)
|
||||
{
|
||||
public HttpClientBuilder socketTimeout(long timeout, TimeUnit unit) {
|
||||
this.socketTimeout = timeout;
|
||||
this.socketTimeoutUnits = unit;
|
||||
return this;
|
||||
|
@ -135,8 +138,7 @@ public class HttpClientBuilder {
|
|||
* @param unit
|
||||
* @return
|
||||
*/
|
||||
public HttpClientBuilder establishConnectionTimeout(long timeout, TimeUnit unit)
|
||||
{
|
||||
public HttpClientBuilder establishConnectionTimeout(long timeout, TimeUnit unit) {
|
||||
this.establishConnectionTimeout = timeout;
|
||||
this.establishConnectionTimeoutUnits = unit;
|
||||
return this;
|
||||
|
@ -287,16 +289,20 @@ public class HttpClientBuilder {
|
|||
cm = new SingleClientConnManager(registry);
|
||||
}
|
||||
BasicHttpParams params = new BasicHttpParams();
|
||||
if (socketTimeout > -1)
|
||||
{
|
||||
|
||||
if (proxyHost != null) {
|
||||
params.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxyHost);
|
||||
}
|
||||
|
||||
if (socketTimeout > -1) {
|
||||
HttpConnectionParams.setSoTimeout(params, (int) socketTimeoutUnits.toMillis(socketTimeout));
|
||||
|
||||
}
|
||||
if (establishConnectionTimeout > -1)
|
||||
{
|
||||
if (establishConnectionTimeout > -1) {
|
||||
HttpConnectionParams.setConnectionTimeout(params, (int) establishConnectionTimeoutUnits.toMillis(establishConnectionTimeout));
|
||||
}
|
||||
DefaultHttpClient client = new DefaultHttpClient(cm, params);
|
||||
|
||||
if (disableCookieCache) {
|
||||
client.setCookieStore(new CookieStore() {
|
||||
@Override
|
||||
|
@ -364,6 +370,28 @@ public class HttpClientBuilder {
|
|||
} else {
|
||||
trustStore(truststore);
|
||||
}
|
||||
|
||||
configureProxyForAuthServerIfProvided(adapterConfig);
|
||||
|
||||
return build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a the proxy to use for auth-server requests if provided.
|
||||
* <p>
|
||||
* If the given {@link AdapterConfig} contains the attribute {@code proxy-url} we use the
|
||||
* given URL as a proxy server, otherwise the proxy configuration is ignored.
|
||||
* </p>
|
||||
*
|
||||
* @param adapterConfig
|
||||
*/
|
||||
private void configureProxyForAuthServerIfProvided(AdapterConfig adapterConfig) {
|
||||
|
||||
if (adapterConfig == null || adapterConfig.getProxyUrl() == null || adapterConfig.getProxyUrl().trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
URI uri = URI.create(adapterConfig.getProxyUrl());
|
||||
this.proxyHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
|
||||
}
|
||||
}
|
|
@ -35,7 +35,8 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
|||
"allow-any-hostname", "disable-trust-manager", "truststore", "truststore-password",
|
||||
"client-keystore", "client-keystore-password", "client-key-password",
|
||||
"always-refresh-token",
|
||||
"register-node-at-startup", "register-node-period", "token-store", "principal-attribute"
|
||||
"register-node-at-startup", "register-node-period", "token-store", "principal-attribute",
|
||||
"proxy-url"
|
||||
})
|
||||
public class AdapterConfig extends BaseAdapterConfig {
|
||||
|
||||
|
@ -68,6 +69,12 @@ public class AdapterConfig extends BaseAdapterConfig {
|
|||
@JsonProperty("turn-off-change-session-id-on-login")
|
||||
protected Boolean turnOffChangeSessionIdOnLogin;
|
||||
|
||||
/**
|
||||
* The Proxy url to use for requests to the auth-server, configurable via the adapter config property {@code proxy-url}.
|
||||
*/
|
||||
@JsonProperty("proxy-url")
|
||||
protected String proxyUrl;
|
||||
|
||||
public boolean isAllowAnyHostname() {
|
||||
return allowAnyHostname;
|
||||
}
|
||||
|
@ -179,4 +186,12 @@ public class AdapterConfig extends BaseAdapterConfig {
|
|||
public void setTurnOffChangeSessionIdOnLogin(Boolean turnOffChangeSessionIdOnLogin) {
|
||||
this.turnOffChangeSessionIdOnLogin = turnOffChangeSessionIdOnLogin;
|
||||
}
|
||||
|
||||
public String getProxyUrl() {
|
||||
return proxyUrl;
|
||||
}
|
||||
|
||||
public void setProxyUrl(String proxyUrl) {
|
||||
this.proxyUrl = proxyUrl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,6 +405,17 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>proxy-url</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Defines the proxy to use for requests sent to the auth-server-url.
|
||||
This is <emphasis>OPTIONAL</emphasis>. Note that only the <emphasis>scheme</emphasis>,
|
||||
<emphasis>host</emphasis> and <emphasis>port</emphasis> of the proxy URL are used.
|
||||
Proxies that require authentication are currently not supported.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</section>
|
||||
|
|
Loading…
Reference in a new issue