8000 Upgrade Resteasy v4 by pedroigor · Pull Request #10917 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,34 @@
package org.keycloak.adapters;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
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;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.StrictHostnameVerifier;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
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.apache.http.cookie.CookieSpecProvider;
import org.apache.http.impl.auth.SPNegoSchemeFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CookieSpecRegistries;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.DefaultCookieSpecProvider;
import org.keycloak.common.util.EnvUtil;
import org.keycloak.common.util.KeystoreUtil;
import org.keycloak.representations.adapters.config.AdapterHttpClientConfig;
Expand All @@ -50,15 +60,15 @@
import java.io.IOException;
import java.net.URI;
import java.security.KeyStore;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;

/**
* Abstraction for creating HttpClients. Allows SSL configuration.
Expand All @@ -67,6 +77,7 @@
* @version $Revision: 1 $
*/
public class HttpClientBuilder {

public static enum HostnameVerificationPolicy {
/**
* Hostname verification is not done on the server's certificate
Expand Down Expand Up @@ -118,7 +129,8 @@ public X509Certificate[] getAcceptedIssuers() {
protected long establishConnectionTimeout = -1;
protected TimeUnit establishConnectionTimeoutUnits = TimeUnit.MILLISECONDS;
protected HttpHost proxyHost;

private SPNegoSchemeFactory spNegoSchemeFactory;
private boolean useSpNego;

/**
* Socket inactivity timeout
Expand Down Expand Up @@ -240,6 +252,16 @@ public boolean verify(String s, SSLSession sslSession) {
}
}

public HttpClientBuilder spNegoSchemeFactory(SPNegoSchemeFactory spnegoSchemeFactory) {
this.spNegoSchemeFactory = spnegoSchemeFactory;
return this;
}

public HttpClientBuilder useSPNego(boolean useSpnego) {
this.useSpNego = useSpnego;
return this;
}

public HttpClient build() {
X509HostnameVerifier verifier = null;
if (this.verifier != null) verifier = new VerifierWrapper(this.verifier);
Expand All @@ -257,7 +279,7 @@ public HttpClient build() {
}
}
try {
SSLSocketFactory sslsf = null;
ConnectionSocketFactory sslsf;
SSLContext theContext = sslContext;
if (disableTrustManager) {
theContext = SSLContext.getInstance("SSL");
Expand All @@ -274,40 +296,85 @@ public HttpClient build() {
tlsContext.init(null, null, null);
sslsf = new SniSSLSocketFactory(tlsContext, verifier);
}
SchemeRegistry registry = new SchemeRegistry();
registry.register(
new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
Scheme httpsScheme = new Scheme("https", 443, sslsf);
registry.register(httpsScheme);
ClientConnectionManager cm = null;

RegistryBuilder<ConnectionSocketFactory> sf = RegistryBuilder.create();

sf.register("http", PlainConnectionSocketFactory.getSocketFactory());
sf.register("https", sslsf);

HttpClientConnectionManager cm;

if (connectionPoolSize > 0) {
ThreadSafeClientConnManager tcm = new ThreadSafeClientConnManager(registry, connectionTTL, connectionTTLUnit);
PoolingHttpClientConnectionManager tcm = new PoolingHttpClientConnectionManager(sf.build());
tcm.setMaxTotal(connectionPoolSize);
if (maxPooledPerRoute == 0) maxPooledPerRoute = connectionPoolSize;
tcm.setDefaultMaxPerRoute(maxPooledPerRoute);
cm = tcm;

} else {
cm = new SingleClientConnManager(registry);
cm = new BasicHttpClientConnectionManager(sf.build());
}
BasicHttpParams params = new BasicHttpParams();
params.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);

SocketConfig.Builder socketConfig = SocketConfig.copy(SocketConfig.DEFAULT);
ConnectionConfig.Builder connConfig = ConnectionConfig.copy(ConnectionConfig.DEFAULT);
RequestConfig.Builder requestConfig = RequestConfig.copy(RequestConfig.DEFAULT);

if (proxyHost != null) {
params.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxyHost);
requestConfig.setProxy(new HttpHost(proxyHost));
}

if (socketTimeout > -1) {
HttpConnectionParams.setSoTimeout(params, (int) socketTimeoutUnits.toMillis(socketTimeout));
requestConfig.setSocketTimeout((int) socketTimeoutUnits.toMillis(socketTimeout));

}
if (establishConnectionTimeout > -1) {
HttpConnectionParams.setConnectionTimeout(params, (int) establishConnectionTimeoutUnits.toMillis(establishConnectionTimeout));
requestConfig.setConnectTimeout((int) establishConnectionTimeoutUnits.toMillis(establishConnectionTimeout));
}

Registry<CookieSpecProvider> cookieSpecs = CookieSpecRegistries.createDefaultBuilder()
.register(CookieSpecs.DEFAULT, new DefaultCookieSpecProvider()).build();

if (useSpNego) {
requestConfig.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.SPNEGO));
}

org.apache.http.impl.client.HttpClientBuilder clientBuilder = org.apache.http.impl.client.HttpClientBuilder.create()
.setDefaultSocketConfig(socketConfig.build())
.setDefaultConnectionConfig(connConfig.build())
.setDefaultRequestConfig(requestConfig.build())
.setDefaultCookieSpecRegistry(cookieSpecs)
.setConnectionManager(cm);

if (spNegoSchemeFactory != null) {
RegistryBuilder<AuthSchemeProvider> authSchemes = RegistryBuilder.create();

authSchemes.register(AuthSchemes.SPNEGO, spNegoSchemeFactory);

clientBuilder.setDefaultAuthSchemeRegistry(authSchemes.build());
}

if (useSpNego) {
Credentials fake = new Credentials() {

@Override
public String getPassword() {
return null;
}

@Override
public Principal getUserPrincipal() {
return null;
}

};

BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, fake);
clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
DefaultHttpClient client = new DefaultHttpClient(cm, params);

if (disableCookieCache) {
client.setCookieStore(new CookieStore() {
clientBuilder.setDefaultCookieStore(new CookieStore() {
@Override
public void addCookie(Cookie cookie) {
//To change body of implemented methods use File | Settings | File Templates.
Expand All @@ -330,7 +397,7 @@ public void clear() {
10BC8 });

}
return client;
return clientBuilder.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package org.keycloak.adapters;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.Configurable;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.CoreConnectionPNames;
import org.hamcrest.CoreMatchers;
Expand All @@ -37,6 +39,9 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.lang.reflect.Field;
import java.util.Optional;

/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author <a href="mailto:brad.culley@spartasystems.com">Brad Culley</a>
Expand Down Expand Up @@ -69,7 +74,22 @@ public void load() {
assertFalse(deployment.isOAuthQueryParameterEnabled());
assertEquals("234234-234234-234234", deployment.getResourceCredentials().get("secret"));
assertEquals(ClientIdAndSecretCredentialsProvider.PROVIDER_ID, deployment.getClientAuthenticator().getId());
assertEquals(20, ((ThreadSafeClientConnManager) deployment.getClient().getConnectionManager()).getMaxTotal());
HttpClient client = deployment.getClient();
int maxPoolConnections = -1;
Field connManager = null;

try {
connManager = client.getClass().getDeclaredField("connManager");
connManager.setAccessible(true);
maxPoolConnections = ((PoolingHttpClientConnectionManager) connManager.get(client)).getMaxTotal();
} catch (Exception cause) {
throw new RuntimeException("Failed to get max pool connections", cause);
} finally {
connManager.setAccessible(false);
}


assertEquals(20, maxPoolConnections);
assertEquals(RelativeUrlsUsed.NEVER, deployment.getRelativeUrls());
assertTrue(deployment.isAlwaysRefreshToken());
assertTrue(deployment.isRegisterNodeAtStartup());
Expand Down Expand Up @@ -113,8 +133,8 @@ public void loadHttpClientTimeoutConfiguration() {
HttpClient client = deployment.getClient();
assertThat(client, CoreMatchers.notNullValue());

long socketTimeout = client.getParams().getIntParameter(CoreConnectionPNames.SO_TIMEOUT, -2);
long connectionTimeout = client.getParams().getIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, -2);
long socketTimeout = ((Configurable) client).getConfig().getSocketTimeout();
long connectionTimeout = ((Configurable) client).getConfig().getConnectTimeout();

assertThat(socketTimeout, CoreMatchers.is(2000L));
assertThat(connectionTimeout, CoreMatchers.is(6000L));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -567,10 +567,11 @@ protected ResteasyClient getResteasyClient() {
}

protected ResteasyClient createResteasyClient() {
return new ResteasyClientBuilder()
return ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder())
.connectionCheckoutTimeout(1, TimeUnit.HOURS)
.connectionTTL(1, TimeUnit.HOURS)
.socketTimeout(1, TimeUnit.HOURS)
Comment thread
pedroigor marked this conversation as resolved.
Resolved
.connectTimeout(1, TimeUnit.HOURS)
.readTimeout(1, TimeUnit.HOURS)
.disableTrustManager().build();
Comment thread
pedroigor marked this conversation as resolved.
Resolved
}

Expand Down
2 changes: 1 addition & 1 deletion examples/cors/database-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion federation/ldap/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion integration/client-cli/admin-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
</includes>
</filter>
<filter>
<artifact>org.jboss.resteasy:resteasy-jaxrs</artifact>
<artifact>org.jboss.resteasy:resteasy-core</artifact>
<includes>
<include>**/**</include>
</includes>
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion model/jpa/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
</dependency>
10BC8 <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion model/legacy-private/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<!-- needed for LegacyExportImportManager that is calling ValidationUtil.validateClient (which is in server-spi-private) might throw a BadRequestException -->
<!-- see: https://github.com/hmlnarik/keycloak/pull/23#discussion_r862293798 -->
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion model/map/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<!-- needed for MapExportImportManager that is calling ValidationUtil.validateClient (which is in server-spi-private) might throw a BadRequestException -->
<!-- see: https://github.com/hmlnarik/keycloak/pull/23#discussion_r862293798 -->
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
<jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec.version>2.0.1.Final</jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec.version>
<jboss.spec.javax.servlet.jsp.jboss-jsp-api_2.3_spec.version>2.0.0.Final</jboss.spec.javax.servlet.jsp.jboss-jsp-api_2.3_spec.version>
<log4j.version>1.2.17</log4j.version>
<resteasy.version>3.15.1.Final</resteasy.version>
<resteasy.version>4.7.4.Final</resteasy.version>
<resteasy.undertow.version>${resteasy.version}</resteasy.undertow.version>
<owasp.html.sanitizer.version>20211018.2</owasp.html.sanitizer.version>
<slf4j-api.version>1.7.30</slf4j-api.version>
Expand Down Expand Up @@ -400,7 +400,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<version>${resteasy.version}</version>
<exclusions>
<exclusion>
Expand Down
2 changes: 1 addition & 1 deletion server-spi-private/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion server-spi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
Loading
0