8000 Switching to Resteasy Reactive by pedroigor · Pull Request #15728 · 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
12 changes: 8 additions & 4 deletions common/src/main/java/org/keycloak/common/util/UriUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static String getHost(String uri) {
}
}

public static MultivaluedHashMap<String, String> decodeQueryString(String queryString) {
public static MultivaluedHashMap<String, String> parseQueryParameters(String queryString, boolean decode) {
MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
if (queryString == null || queryString.equals("")) return map;

Expand All @@ -71,9 +71,9 @@ public static MultivaluedHashMap<String, String> decodeQueryString(String queryS
String[] nv = param.split("=", 2);
try
{
String name = URLDecoder.decode(nv[0], "UTF-8");
String name = decode ? URLDecoder.decode(nv[0], "UTF-8") : nv[0];
String val = nv.length > 1 ? nv[1] : "";
map.add(name, URLDecoder.decode(val, "UTF-8"));
map.add(name, decode ? URLDecoder.decode(val, "UTF-8") : val);
}
catch (UnsupportedEncodingException e)
{
Expand All @@ -84,7 +84,7 @@ public static MultivaluedHashMap<String, String> decodeQueryString(String queryS
{
try
{
String name = URLDecoder.decode(param, "UTF-8");
String name = decode ? URLDecoder.decode(param, "UTF-8") : param;
map.add(name, "");
}
catch (UnsupportedEncodingException e)
Expand All @@ -96,6 +96,10 @@ public static MultivaluedHashMap<String, String> decodeQueryString(String queryS
return map;
}

public static MultivaluedHashMap<String, String> decodeQueryString(String queryString) {
return parseQueryParameters(queryString, true);
}

public static String stripQueryParam(String url, String name){
return url.replaceFirst("[\\?&]"+name+"=[^&]*$|"+name+"=[^&]*&", "");
}
Expand Down
Empty file.
Empty file.
4 changes: 2 additions & 2 deletions quarkus/deployment/pom.xml
8 10BC8
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-deployment</artifactId>
<artifactId>quarkus-resteasy-reactive-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson-deployment</artifactId>
<artifactId>quarkus-resteasy-reactive-jackson-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,9 @@
import io.quarkus.hibernate.orm.deployment.PersistenceXmlDescriptorBuildItem;
import io.quarkus.hibernate.orm.deployment.integration.HibernateOrmIntegrationRuntimeConfiguredBuildItem;
import io.quarkus.hibernate.orm.deployment.spi.AdditionalJpaModelBuildItem;
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
import io.quarkus.resteasy.reactive.server.spi.MethodScannerBuildItem;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.runtime.configuration.ProfileManager;
import io.quarkus.vertx.http.deployment.FilterBuildItem;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.smallrye.config.ConfigValue;
import org.hibernate.cfg.AvailableSettings;
Expand All @@ -55,8 +53,10 @@
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;
import org.jboss.logging.Logger;
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
import org.jboss.resteasy.reactive.server.model.HandlerChainCustomizer;
import org.jboss.resteasy.reactive.server.processor.scanning.MethodScanner;
import org.jboss.resteasy.spi.ResteasyDeployment;
import org.keycloak.Config;
import org.keycloak.authentication.AuthenticatorSpi;
Expand Down Expand Up @@ -93,14 +93,15 @@
import org.keycloak.quarkus.runtime.configuration.QuarkusPropertiesConfigSource;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import org.keycloak.quarkus.runtime.integration.jaxrs.QuarkusKeycloakApplication;
import org.keycloak.quarkus.runtime.integration.resteasy.KeycloakHandlerChainCustomizer;
import org.keycloak.quarkus.runtime.integration.web.NotFoundHandler;
import org.keycloak.quarkus.runtime.services.health.KeycloakReadyHealthCheck;
import org.keycloak.quarkus.runtime.storage.database.jpa.NamedJpaConnectionProviderFactory;
import org.keycloak.quarkus.runtime.themes.FlatClasspathThemeResourceProviderFactory;
import org.keycloak.representations.provider.ScriptProviderDescriptor;
import org.keycloak.representations.provider.ScriptProviderMetadata;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.theme.ClasspathThemeProviderFactory;
import org.keycloak.theme.ClasspathThemeResourceProviderFactory;
import org.keycloak.theme.FolderThemeProviderFactory;
Expand Down Expand Up @@ -181,10 +182,6 @@ class KeycloakProcessor {
ClasspathThemeResourceProviderFactory.class,
JarThemeProviderFactory.class,
JpaMapStorageProviderFactory.class);
public static final String QUARKUS_HEALTH_ROOT_PROPERTY = "quarkus.smallrye-health.root-path";
public static final String QUARKUS_METRICS_PATH_PROPERTY = "quarkus.micrometer.export.prometheus.path";
public static final String QUARKUS_DEFAULT_HEALTH_PATH = "health";
public static final String QUARKUS_DEFAULT_METRICS_PATH = "metrics";

static {
DEPLOYEABLE_SCRIPT_PROVIDERS.put(AUTHENTICATORS, KeycloakProcessor::registerScriptAuthenticator);
Expand Down Expand Up @@ -593,27 +590,6 @@ void indexLegacyJpaStore(BuildProducer<IndexDependencyBuildItem> indexDependency
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.keycloak", "keycloak-model-jpa"));
}

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
void initializeFilter(BuildProducer<FilterBuildItem> filters, KeycloakRecorder recorder, NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) {

List<String> ignoredPaths = new ArrayList<>();

if (isHealthEnabled()) {
ignoredPaths.add(nonApplicationRootPathBuildItem.
resolvePath(getOptionalValue(QUARKUS_HEALTH_ROOT_PROPERTY)
.orElse(QUARKUS_DEFAULT_HEALTH_PATH)));
}

if (isMetricsEnabled()) {
ignoredPaths.add(nonApplicationRootPathBuildItem.
resolvePath(getOptionalValue(QUARKUS_METRICS_PATH_PROPERTY)
.orElse(QUARKUS_DEFAULT_METRICS_PATH)));
}

filters.produce(new FilterBuildItem(recorder.createRequestFilter(ignoredPaths),FilterBuildItem.AUTHORIZATION - 10));
}

@BuildStep
void disableMetricsEndpoint(BuildProducer<RouteBuildItem> routes) {
if (!isMetricsEnabled()) {
Expand Down Expand Up @@ -641,15 +617,19 @@ void disableHealthEndpoint(BuildProducer<RouteBuildItem> routes, BuildProducer<B
}

@BuildStep
void configureResteasy(BuildProducer<ResteasyDeploymentCustomizerBuildItem> deploymentCustomizerProducer) {
deploymentCustomizerProducer.produce(new ResteasyDeploymentCustomizerBuildItem(new Consumer<ResteasyDeployment>() {
void configureResteasy(CombinedIndexBuildItem index,
BuildProducer<BuildTimeConditionBuildItem> buildTimeConditionBuildItemBuildProducer,
BuildProducer<MethodScannerBuildItem> scanner) {
buildTimeConditionBuildItemBuildProducer.produce(new BuildTimeConditionBuildItem(index.getIndex().getClassByName(DotName.createSimple(
KeycloakApplication.class.getName())), false));
Comment thread
pedroigor marked this conversation as resolved.
Resolved

KeycloakHandlerChainCustomizer chainCustomizer = new KeycloakHandlerChainCustomizer();

scanner.produce(new MethodScannerBuildItem(new MethodScanner() {
@Override
public void accept(ResteasyDeployment resteasyDeployment) {
// we need to explicitly set the application to avoid errors at build time due to the application
// from keycloak-services also being added to the index
resteasyDeployment.setApplicationClass(QuarkusKeycloakApplication.class.getName());
// we need to disable the sanitizer to avoid escaping text/html responses from the server
resteasyDeployment.setProperty(ResteasyContextParameters.RESTEASY_DISABLE_HTML_SANITIZER, Boolean.TRUE);
public List<HandlerChainCustomizer> scan(MethodInfo method, ClassInfo actualEndpointClass,
Map<String, Object> methodContext) {
return List.of(chainCustomizer);
}
}));
}
Expand Down
4 changes: 2 additions & 2 deletions quarkus/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
import org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter;
import org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
Expand Down Expand Up @@ -141,29 +140,6 @@ public void contributeRuntimeProperties(BiConsumer<String, Object> propertyColle
};
}

public QuarkusRequestFilter createRequestFilter(List<String> ignoredPaths) {
return new QuarkusRequestFilter(createIgnoredHttpPathsPredicate(ignoredPaths));
}

private Predicate<RoutingContext> createIgnoredHttpPathsPredicate(List<String> ignoredPaths) {
if (ignoredPaths == null || ignoredPaths.isEmpty()) {
return null;
}

return new Predicate<>() {
@Override
public boolean test(RoutingContext context) {
for (String ignoredPath : ignoredPaths) {
if (context.request().uri().startsWith(ignoredPath)) {
return true;
}
}

return false;
}
};
}

public void setCryptoProvider(FipsMode fipsMode) {
String cryptoProvider = fipsMode.getProviderClassName();

Expand Down
Original file line number Diff line number Diff 10BC8 line change
Expand Up @@ -107,6 +107,16 @@ public static Optional<String> getOptionalKcValue(String propertyName) {
return getOptionalValue(NS_KEYCLOAK_PREFIX.concat(propertyName));
}

public static Optional<Boolean> getOptionalBooleanKcValue(String propertyName) {
Optional<String> value = getOptionalValue(NS_KEYCLOAK_PREFIX.concat(propertyName));

if (value.isPresent()) {
return value.map(Boolean::parseBoolean);
}

return Optional.empty();
}

public static Optional<Boolean> getOptionalBooleanValue(String name) {
return getOptionalValue(name).map(Boolean::parseBoolean);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ private boolean isHostFromFrontEndUrl(UriInfo originalUriInfo) {

protected URI getRealmFrontEndUrl() {
KeycloakSession session = Resteasy.getContextData(KeycloakSession.class);

if (session == null) {
return null;
}

RealmModel realm = session.getContext().getRealm();

if (realm == null) {
Expand Down Expand Up @@ -300,8 +305,7 @@ public void init(Config.Scope config) {
}

private int getRequestPort(UriInfo uriInfo) {
KeycloakSession session = Resteasy.getContextData(KeycloakSession.class);
return session.getContext().getHttpRequest().getUri().getBaseUri().getPort();
return uriInfo.getBaseUri().getPort();
}

private <T> T fromBaseUriOrDefault(Function<URI, T> resolver, URI baseUri, T defaultValue) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
package org.keycloak.quarkus.runtime.integration;

import org.keycloak.models.KeycloakSession;
import org.keycloak.quarkus.runtime.integration.resteasy.QuarkusKeycloakContext;
import org.keycloak.services.DefaultKeycloakContext;
import org.keycloak.services.DefaultKeycloakSession;
import org.keycloak.services.DefaultKeycloakSessionFactory;

public class QuarkusKeycloakSession extends DefaultKeycloakSession {
public final class QuarkusKeycloakSession extends DefaultKeycloakSession {

public QuarkusKeycloakSession(DefaultKeycloakSessionFactory factory) {
super(factory);
Expand Down

This file was deleted.

Loading
0