Upgrade Resteasy v4

Closes #10916

Co-authored-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
Pedro Igor 2022-03-24 10:21:36 -03:00 committed by Bruno Oliveira da Silva
parent 2ce3ba291f
commit 5b48d72730
36 changed files with 200 additions and 144 deletions

View file

@ -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;
@ -50,15 +60,15 @@ import javax.net.ssl.X509TrustManager;
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.
@ -67,6 +77,7 @@ import org.apache.http.client.params.CookiePolicy;
* @version $Revision: 1 $
*/
public class HttpClientBuilder {
public static enum HostnameVerificationPolicy {
/**
* Hostname verification is not done on the server's certificate
@ -118,7 +129,8 @@ public class HttpClientBuilder {
protected long establishConnectionTimeout = -1;
protected TimeUnit establishConnectionTimeoutUnits = TimeUnit.MILLISECONDS;
protected HttpHost proxyHost;
private SPNegoSchemeFactory spNegoSchemeFactory;
private boolean useSpNego;
/**
* Socket inactivity timeout
@ -240,6 +252,16 @@ public class HttpClientBuilder {
}
}
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);
@ -257,7 +279,7 @@ public class HttpClientBuilder {
}
}
try {
SSLSocketFactory sslsf = null;
ConnectionSocketFactory sslsf;
SSLContext theContext = sslContext;
if (disableTrustManager) {
theContext = SSLContext.getInstance("SSL");
@ -274,40 +296,85 @@ public class HttpClientBuilder {
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.
@ -330,7 +397,7 @@ public class HttpClientBuilder {
});
}
return client;
return clientBuilder.build();
} catch (Exception e) {
throw new RuntimeException(e);
}

View file

@ -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;
@ -37,6 +39,9 @@ import static org.junit.Assert.assertEquals;
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>
@ -69,7 +74,22 @@ public class KeycloakDeploymentBuilderTest {
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());
@ -113,8 +133,8 @@ public class KeycloakDeploymentBuilderTest {
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));

View file

@ -567,10 +567,11 @@ public class KeycloakInstalled {
}
protected ResteasyClient createResteasyClient() {
return new ResteasyClientBuilder()
return ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder())
.connectionCheckoutTimeout(1, TimeUnit.HOURS)
.connectionTTL(1, TimeUnit.HOURS)
.socketTimeout(1, TimeUnit.HOURS)
.connectTimeout(1, TimeUnit.HOURS)
.readTimeout(1, TimeUnit.HOURS)
.disableTrustManager().build();
}

View file

@ -35,7 +35,7 @@
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -57,7 +57,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -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>

View file

@ -1,23 +0,0 @@
org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider
org.jboss.resteasy.plugins.providers.DataSourceProvider
org.jboss.resteasy.plugins.providers.DocumentProvider
org.jboss.resteasy.plugins.providers.DefaultTextPlain
org.jboss.resteasy.plugins.providers.StringTextStar
org.jboss.resteasy.plugins.providers.SourceProvider
org.jboss.resteasy.plugins.providers.InputStreamProvider
org.jboss.resteasy.plugins.providers.ReaderProvider
org.jboss.resteasy.plugins.providers.ByteArrayProvider
org.jboss.resteasy.plugins.providers.FormUrlEncodedProvider
org.jboss.resteasy.plugins.providers.JaxrsFormProvider
org.jboss.resteasy.plugins.providers.FileProvider
org.jboss.resteasy.plugins.providers.FileRangeWriter
org.jboss.resteasy.plugins.providers.StreamingOutputProvider
org.jboss.resteasy.plugins.providers.IIOImageProvider
org.jboss.resteasy.plugins.providers.SerializableProvider
org.jboss.resteasy.plugins.interceptors.CacheControlFeature
org.jboss.resteasy.plugins.interceptors.encoding.AcceptEncodingGZIPInterceptor
org.jboss.resteasy.plugins.interceptors.encoding.AcceptEncodingGZIPFilter
org.jboss.resteasy.plugins.interceptors.encoding.ClientContentEncodingAnnotationFeature
org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor
org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor
org.jboss.resteasy.plugins.interceptors.encoding.ServerContentEncodingAnnotationFeature

View file

@ -90,7 +90,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -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>

View file

@ -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>

View file

@ -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>
@ -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>

View file

@ -43,7 +43,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -38,7 +38,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -16,7 +16,7 @@
*/
package org.keycloak.models;
import org.jboss.resteasy.specimpl.ResteasyUriBuilder;
import org.jboss.resteasy.spi.ResteasyUriBuilder;
import org.keycloak.urls.HostnameProvider;
import org.keycloak.urls.UrlType;

View file

@ -107,7 +107,12 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -37,7 +37,7 @@ public class DBAllocatorServiceClient {
this.allocatorServletURI = URI.create(allocatorServletURI);
this.retryPolicy = retryPolicy != null ? retryPolicy : new IncrementalBackoffRetryPolicy();
this.restClient = new ResteasyClientBuilder().httpEngine(createEngine()).build();
this.restClient = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(createEngine()).build();
}
private final ApacheHttpClient43Engine createEngine() {

View file

@ -57,7 +57,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>

View file

@ -120,12 +120,7 @@
</artifactItem>
<artifactItem>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>${tomcat.resteasy.version}</version>
</artifactItem>
<artifactItem>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<artifactId>resteasy-core</artifactId>
<version>${tomcat.resteasy.version}</version>
</artifactItem>
<artifactItem>

View file

@ -49,6 +49,7 @@ import org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext;
import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData;
import org.jboss.arquillian.container.spi.client.protocol.metadata.Servlet;
import org.jboss.logging.Logger;
import org.jboss.resteasy.core.ResteasyDeploymentImpl;
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.jboss.shrinkwrap.api.Archive;
@ -139,7 +140,7 @@ public class UndertowAppServer implements DeployableContainer<UndertowAppServerC
} else if (applicationClassNode.isPresent()) {
String applicationPath = applicationClassNode.get().getPath().get();
ResteasyDeployment deployment = new ResteasyDeployment();
ResteasyDeployment deployment = new ResteasyDeploymentImpl();
deployment.setApplicationClass(extractClassName(applicationPath));
di = new UndertowDeployerHelper().getDeploymentInfo(configuration, (WebArchive) archive, undertow.undertowDeployment(deployment));
} else {
@ -253,7 +254,7 @@ public class UndertowAppServer implements DeployableContainer<UndertowAppServerC
.filter(clazz -> clazz.isAnnotationPresent(Path.class))
.collect(Collectors.toSet());
ResteasyDeployment deployment = new ResteasyDeployment();
ResteasyDeployment deployment = new ResteasyDeploymentImpl();
deployment.setApplication(new RestSamlApplicationConfig(classes));
return deployment;
}

View file

@ -52,7 +52,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -38,6 +38,7 @@ import org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext;
import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData;
import org.jboss.arquillian.container.spi.client.protocol.metadata.Servlet;
import org.jboss.logging.Logger;
import org.jboss.resteasy.core.ResteasyDeploymentImpl;
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
import org.jboss.resteasy.spi.ResteasyDeployment;
@ -81,19 +82,17 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
Map<String, String> deployedArchivesToContextPath = new ConcurrentHashMap<>();
private DeploymentInfo createAuthServerDeploymentInfo() {
ResteasyDeployment deployment = new ResteasyDeployment();
ResteasyDeployment deployment = new ResteasyDeploymentImpl();
deployment.setApplicationClass(KeycloakApplication.class.getName());
// RESTEASY-2034
deployment.setProperty(ResteasyContextParameters.RESTEASY_DISABLE_HTML_SANITIZER, true);
// Prevent double gzip encoding of resources
deployment.getDisabledProviderClasses().add("org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor");
DeploymentInfo di = undertow.undertowDeployment(deployment);
di.setClassLoader(getClass().getClassLoader());
di.setContextPath("/auth");
di.setDeploymentName("Keycloak");
di.setDefaultEncoding("UTF-8");
if (configuration.getKeycloakConfigPropertyOverridesMap() != null) {
try {
di.addInitParameter(JsonConfigProviderFactory.SERVER_CONTEXT_CONFIG_PROPERTY_OVERRIDES,

View file

@ -34,7 +34,7 @@
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View file

@ -16,6 +16,9 @@
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<!-- wherever this is being deployed, the Servlet API spec should already be there.
Therefore, make this provided to avoid mixing APIs on the target -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
@ -44,7 +47,11 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>

View file

@ -45,7 +45,7 @@ public class KeycloakTestingClient implements AutoCloseable {
if (resteasyClient != null) {
client = resteasyClient;
} else {
ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder();
ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder();
resteasyClientBuilder.connectionPoolSize(10);
if (serverUrl.startsWith("https")) {
// Disable PKIX path validation errors when running tests using SSL

View file

@ -35,16 +35,15 @@ import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.jboss.resteasy.client.jaxrs.ClientHttpEngine;
import org.jboss.resteasy.client.jaxrs.ClientHttpEngineBuilder43;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.engines.ClientHttpEngineBuilder43;
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.models.Constants;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
import static org.keycloak.testsuite.utils.io.IOUtil.PROJECT_BUILD_DIRECTORY;
@ -117,7 +116,7 @@ public class AdminClientUtil {
}
public static ResteasyClient createResteasyClient(boolean ignoreUnknownProperties, Boolean followRedirects) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder();
ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder();
if ("true".equals(System.getProperty("auth.server.ssl.required"))) {
File trustore = new File(PROJECT_BUILD_DIRECTORY, "dependency/keystore/keycloak.truststore");
@ -187,7 +186,7 @@ public class AdminClientUtil {
engine = super.createEngine(cm, rcBuilder, defaultProxy, responseBufferSize, verifier, theContext);
}
if (followRedirects != null) {
((ApacheHttpClient4Engine) engine).setFollowRedirects(followRedirects);
engine.setFollowRedirects(followRedirects);
}
return engine;
}

View file

@ -280,7 +280,7 @@ public class ImpersonationTest extends AbstractKeycloakTest {
// Return the SSO cookie from the impersonated session
protected Set<Cookie> testSuccessfulImpersonation(String admin, String adminRealm) {
ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder();
ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder();
resteasyClientBuilder.connectionPoolSize(10);
resteasyClientBuilder.httpEngine(AdminClientUtil.getCustomClientHttpEngine(resteasyClientBuilder, 10, null));
ResteasyClient resteasyClient = resteasyClientBuilder.build();
@ -392,7 +392,7 @@ public class ImpersonationTest extends AbstractKeycloakTest {
// Return the SSO cookie from the impersonated session
protected Set<Cookie> testSuccessfulServiceAccountImpersonation(UserRepresentation serviceAccount, String serviceAccountRealm) {
ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder();
ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder();
resteasyClientBuilder.connectionPoolSize(10);
resteasyClientBuilder.httpEngine(AdminClientUtil.getCustomClientHttpEngine(resteasyClientBuilder, 10, null));
ResteasyClient resteasyClient = resteasyClientBuilder.build();

View file

@ -21,7 +21,6 @@ import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
import java.net.URI;
import java.security.Principal;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
@ -35,16 +34,13 @@ import javax.naming.directory.InitialDirContext;
import javax.security.sasl.Sasl;
import javax.ws.rs.core.Response;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.HttpClient;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.ietf.jgss.GSSCredential;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@ -262,33 +258,14 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest {
cleanupApacheHttpClient();
}
DefaultHttpClient httpClient = (DefaultHttpClient) new HttpClientBuilder()
HttpClient httpClient = new HttpClientBuilder()
.disableCookieCache(false)
.spNegoSchemeFactory(spnegoSchemeFactory)
.useSPNego(useSpnego)
.build();
httpClient.getAuthSchemes().register(AuthSchemes.SPNEGO, spnegoSchemeFactory);
if (useSpnego) {
Credentials fake = new Credentials() {
@Override
public String getPassword() {
return null;
}
@Override
public Principal getUserPrincipal() {
return null;
}
};
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(null, -1, null),
fake);
}
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
client = new ResteasyClientBuilder().httpEngine(engine).build();
ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient);
client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(engine).build();
}

View file

@ -22,6 +22,7 @@ import org.apache.http.auth.Credentials;
import org.apache.http.impl.auth.SPNegoScheme;
import org.apache.http.impl.auth.SPNegoSchemeFactory;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
@ -66,6 +67,10 @@ public class KeycloakSPNegoSchemeFactory extends SPNegoSchemeFactory {
return new KeycloakSPNegoScheme(isStripPort(), isUseCanonicalHostname());
}
@Override
public AuthScheme create(HttpContext context) {
return new KeycloakSPNegoScheme(isStripPort(), isUseCanonicalHostname());
}
public class KeycloakSPNegoScheme extends SPNegoScheme {

View file

@ -24,7 +24,7 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.hamcrest.Matchers;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
@ -126,8 +126,8 @@ public class LoginPageTest extends AbstractI18NTest {
ProfileAssume.assumeCommunity();
try(CloseableHttpClient httpClient = (CloseableHttpClient) new HttpClientBuilder().build()) {
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient);
ResteasyClient client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(engine).build();
loginPage.open();
@ -264,12 +264,12 @@ public class LoginPageTest extends AbstractI18NTest {
final String realmLocalizationMessageValue = "Localization Test";
try(CloseableHttpClient httpClient = (CloseableHttpClient) new HttpClientBuilder().build()) {
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient);
testRealm().localization().saveRealmLocalizationText(locale, realmLocalizationMessageKey,
realmLocalizationMessageValue);
ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
ResteasyClient client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(engine).build();
loginPage.open();

View file

@ -35,6 +35,12 @@
<artifactId>junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>

View file

@ -130,7 +130,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>

View file

@ -71,10 +71,6 @@
<artifactId>dom4j</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
@ -85,7 +81,7 @@
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<artifactId>resteasy-core</artifactId>
<exclusions>
<exclusion>
<groupId>log4j</groupId>

View file

@ -23,7 +23,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.common.util.Resteasy;
import org.keycloak.common.util.SystemEnvProperties;
import org.keycloak.util.JsonSerialization;
@ -38,7 +38,7 @@ public class JsonConfigProviderFactory extends org.keycloak.services.util.JsonCo
private Map<String, String> getPropertyOverrides() {
ServletContext context = ResteasyProviderFactory.getContextData(ServletContext.class);
ServletContext context = Resteasy.getContextData(ServletContext.class);
Map<String, String> propertyOverridesMap = new HashMap<>();
String propertyOverrides = context.getInitParameter(SERVER_CONTEXT_CONFIG_PROPERTY_OVERRIDES);

View file

@ -23,6 +23,7 @@ import io.undertow.servlet.api.DefaultServletConfig;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.FilterInfo;
import org.jboss.logging.Logger;
import org.jboss.resteasy.core.ResteasyDeploymentImpl;
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
import org.jboss.resteasy.spi.ResteasyDeployment;
@ -396,7 +397,7 @@ public class KeycloakServer {
public void start() throws Throwable {
long start = System.currentTimeMillis();
ResteasyDeployment deployment = new ResteasyDeployment();
ResteasyDeployment deployment = new ResteasyDeploymentImpl();
deployment.setApplicationClass(KeycloakApplication.class.getName());

View file

@ -1,10 +1,10 @@
package org.keycloak.testsuite;
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.core.ResteasyContext;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.common.util.ResteasyProvider;
public class Resteasy3Provider implements ResteasyProvider {
public class Resteasy4Provider implements ResteasyProvider {
@Override
public <R> R getContextData(Class<R> type) {
@ -13,18 +13,18 @@ public class Resteasy3Provider implements ResteasyProvider {
@Override
public void pushDefaultContextObject(Class type, Object instance) {
ResteasyProviderFactory.getInstance().getContextData(Dispatcher.class).getDefaultContextObjects()
ResteasyProviderFactory.getInstance().getContextData(org.jboss.resteasy.spi.Dispatcher.class).getDefaultContextObjects()
.put(type, instance);
}
@Override
public void pushContext(Class type, Object instance) {
ResteasyProviderFactory.getInstance().pushContext(type, instance);
ResteasyContext.pushContext(type, instance);
}
@Override
public void clearContextData() {
ResteasyProviderFactory.getInstance().clearContextData();
ResteasyContext.clearContextData();
}
}

View file

@ -1 +1 @@
org.keycloak.testsuite.Resteasy3Provider
org.keycloak.testsuite.Resteasy4Provider