Skip to content

Commit

Permalink
Merge pull request #39068 from michalvavrik/feature/oidc-blocking-dns…
Browse files Browse the repository at this point in the history
…-lookup

Optionally run DNS lookup for OIDC server requests on worker thread
  • Loading branch information
gastaldi authored Feb 29, 2024
2 parents da5461a + 6a29b34 commit 1764bf3
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ protected static Uni<OidcClient> createOidcClientUni(OidcClientConfig oidcConfig

OidcCommonUtils.setHttpClientOptions(oidcConfig, tlsConfig, options);

WebClient client = WebClient.create(new io.vertx.mutiny.core.Vertx(vertx.get()), options);
var mutinyVertx = new io.vertx.mutiny.core.Vertx(vertx.get());
WebClient client = WebClient.create(mutinyVertx, options);

Map<OidcEndpoint.Type, List<OidcRequestFilter>> oidcRequestFilters = OidcCommonUtils.getOidcRequestFilters();

Expand All @@ -139,7 +140,8 @@ protected static Uni<OidcClient> createOidcClientUni(OidcClientConfig oidcConfig
OidcCommonUtils.getOidcEndpointUrl(authServerUriString, oidcConfig.tokenPath),
OidcCommonUtils.getOidcEndpointUrl(authServerUriString, oidcConfig.revokePath)));
} else {
tokenUrisUni = discoverTokenUris(client, oidcRequestFilters, authServerUriString.toString(), oidcConfig);
tokenUrisUni = discoverTokenUris(client, oidcRequestFilters, authServerUriString.toString(), oidcConfig,
mutinyVertx);
}
}
return tokenUrisUni.onItemOrFailure()
Expand Down Expand Up @@ -220,9 +222,11 @@ private static void setGrantClientParams(OidcClientConfig oidcConfig, MultiMap g

private static Uni<OidcConfigurationMetadata> discoverTokenUris(WebClient client,
Map<OidcEndpoint.Type, List<OidcRequestFilter>> oidcRequestFilters,
String authServerUrl, OidcClientConfig oidcConfig) {
String authServerUrl, OidcClientConfig oidcConfig, io.vertx.mutiny.core.Vertx vertx) {
final long connectionDelayInMillisecs = OidcCommonUtils.getConnectionDelayInMillis(oidcConfig);
return OidcCommonUtils.discoverMetadata(client, oidcRequestFilters, authServerUrl, connectionDelayInMillisecs)
return OidcCommonUtils
.discoverMetadata(client, oidcRequestFilters, authServerUrl, connectionDelayInMillisecs, vertx,
oidcConfig.useBlockingDnsLookup)
.onItem().transform(json -> new OidcConfigurationMetadata(json.getString("token_endpoint"),
json.getString("revocation_endpoint")));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ public class OidcCommonConfig {
@ConfigItem(defaultValue = "10s")
public Duration connectionTimeout = Duration.ofSeconds(10);

/**
* Whether DNS lookup should be performed on the worker thread.
* Use this option when you can see logged warnings about blocked Vert.x event loop by HTTP requests to OIDC server.
*/
@ConfigItem(defaultValue = "false")
public boolean useBlockingDnsLookup;

/**
* The maximum size of the connection pool used by the WebClient.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.URI;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -20,6 +22,8 @@
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.concurrent.Callable;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -54,8 +58,10 @@
import io.vertx.core.net.KeyStoreOptions;
import io.vertx.core.net.ProxyOptions;
import io.vertx.mutiny.core.MultiMap;
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.core.buffer.Buffer;
import io.vertx.mutiny.ext.web.client.HttpRequest;
import io.vertx.mutiny.ext.web.client.HttpResponse;
import io.vertx.mutiny.ext.web.client.WebClient;

public class OidcCommonUtils {
Expand Down Expand Up @@ -433,7 +439,7 @@ public static Predicate<? super Throwable> oidcEndpointNotAvailable() {
}

public static Uni<JsonObject> discoverMetadata(WebClient client, Map<OidcEndpoint.Type, List<OidcRequestFilter>> filters,
String authServerUrl, long connectionDelayInMillisecs) {
String authServerUrl, long connectionDelayInMillisecs, Vertx vertx, boolean blockingDnsLookup) {
final String discoveryUrl = getDiscoveryUri(authServerUrl);
HttpRequest<Buffer> request = client.getAbs(discoveryUrl);
if (!filters.isEmpty()) {
Expand All @@ -443,7 +449,7 @@ public static Uni<JsonObject> discoverMetadata(WebClient client, Map<OidcEndpoin
filter.filter(request, null, requestProps);
}
}
return request.send().onItem().transform(resp -> {
return sendRequest(vertx, request, blockingDnsLookup).onItem().transform(resp -> {
if (resp.statusCode() == 200) {
return resp.bodyAsJsonObject();
} else {
Expand Down Expand Up @@ -536,4 +542,37 @@ public static List<OidcRequestFilter> getMatchingOidcRequestFilters(Map<OidcEndp
}

}

public static Uni<HttpResponse<Buffer>> sendRequest(io.vertx.core.Vertx vertx, HttpRequest<Buffer> request,
boolean blockingDnsLookup) {
if (blockingDnsLookup) {
return sendRequest(new Vertx(vertx), request, true);
} else {
return request.send();
}
}

public static Uni<HttpResponse<Buffer>> sendRequest(Vertx vertx, HttpRequest<Buffer> request, boolean blockingDnsLookup) {
if (blockingDnsLookup) {
return vertx.executeBlocking(new Callable<Void>() {
@Override
public Void call() {
try {
// cache DNS lookup
InetAddress.getByName(request.host());
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
return null;
}
}).flatMap(new Function<Void, Uni<? extends HttpResponse<Buffer>>>() {
@Override
public Uni<? extends HttpResponse<Buffer>> apply(Void unused) {
return request.send();
}
});
} else {
return request.send();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ quarkus.log.category."com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyle
quarkus.log.category."io.quarkus.oidc.runtime.TenantConfigContext".level=DEBUG
quarkus.log.file.enable=true

# use blocking DNS lookup so that we have it tested somewhere
quarkus.oidc.use-blocking-dns-lookup=true
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,22 @@ public OidcConfigurationMetadata getMetadata() {
}

public Uni<JsonWebKeySet> getJsonWebKeySet(OidcRequestContextProperties contextProperties) {
return filter(OidcEndpoint.Type.JWKS, client.getAbs(metadata.getJsonWebKeySetUri()), null, contextProperties).send()
return OidcCommonUtils
.sendRequest(vertx,
filter(OidcEndpoint.Type.JWKS, client.getAbs(metadata.getJsonWebKeySetUri()), null, contextProperties),
oidcConfig.useBlockingDnsLookup)
.onItem()
.transform(resp -> getJsonWebKeySet(resp));
}

public Uni<UserInfo> getUserInfo(String token) {
LOG.debugf("Get UserInfo on: %s auth: %s", metadata.getUserInfoUri(), OidcConstants.BEARER_SCHEME + " " + token);
return filter(OidcEndpoint.Type.USERINFO, client.getAbs(metadata.getUserInfoUri()), null, null)
.putHeader(AUTHORIZATION_HEADER, OidcConstants.BEARER_SCHEME + " " + token)
.send().onItem().transform(resp -> getUserInfo(resp));
return OidcCommonUtils
.sendRequest(vertx,
filter(OidcEndpoint.Type.USERINFO, client.getAbs(metadata.getUserInfoUri()), null, null)
.putHeader(AUTHORIZATION_HEADER, OidcConstants.BEARER_SCHEME + " " + token),
oidcConfig.useBlockingDnsLookup)
.onItem().transform(resp -> getUserInfo(resp));
}

public Uni<TokenIntrospection> introspectToken(String token) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,8 @@ protected static Uni<OidcProviderClient> createOidcClientUni(OidcTenantConfig oi
WebClientOptions options = new WebClientOptions();

OidcCommonUtils.setHttpClientOptions(oidcConfig, tlsConfig, options);

WebClient client = WebClient.create(new io.vertx.mutiny.core.Vertx(vertx), options);
var mutinyVertx = new io.vertx.mutiny.core.Vertx(vertx);
WebClient client = WebClient.create(mutinyVertx, options);

Map<OidcEndpoint.Type, List<OidcRequestFilter>> oidcRequestFilters = OidcCommonUtils.getOidcRequestFilters();

Expand All @@ -481,7 +481,8 @@ protected static Uni<OidcProviderClient> createOidcClientUni(OidcTenantConfig oi
} else {
final long connectionDelayInMillisecs = OidcCommonUtils.getConnectionDelayInMillis(oidcConfig);
metadataUni = OidcCommonUtils
.discoverMetadata(client, oidcRequestFilters, authServerUriString, connectionDelayInMillisecs)
.discoverMetadata(client, oidcRequestFilters, authServerUriString, connectionDelayInMillisecs, mutinyVertx,
oidcConfig.useBlockingDnsLookup)
.onItem()
.transform(new Function<JsonObject, OidcConfigurationMetadata>() {
@Override
Expand Down

0 comments on commit 1764bf3

Please sign in to comment.