From d511b632a9e14a0e86af2f3a26f1725d7558b911 Mon Sep 17 00:00:00 2001 From: Pavel Ptashyts <49400901+pavel-ptashyts@users.noreply.github.com> Date: Mon, 20 Jul 2026 21:16:51 +0200 Subject: [PATCH] Document blocking SPNEGO hostname lookup Canonical-hostname resolution is opt-in but performs a synchronous JVM lookup while deriving the Kerberos service principal. Authentication retries can invoke that lookup on a Netty event-loop thread. Document the blocking behavior and direct users with a known principal to the existing explicit service-principal setting. Codex on behalf of Pavel Ptashyts Co-Authored-By: Codex --- README.md | 5 +++++ client/src/main/java/org/asynchttpclient/Realm.java | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/README.md b/README.md index bf66fe2e7..6ba6f9ba5 100644 --- a/README.md +++ b/README.md @@ -396,6 +396,11 @@ Response response = client Supported schemes: **Basic**, **Digest**, **NTLM**, **SPNEGO/Kerberos**, **SCRAM-SHA-256**. +SPNEGO/Kerberos canonical-hostname resolution is disabled by default. Enabling it with +`setUseCanonicalHostname(true)` performs a blocking JVM lookup while generating the authentication token; during +an authentication retry, that work can run on a Netty event-loop thread. When the service principal name is known, +provide it with `setServicePrincipalName(...)` instead of enabling hostname canonicalization. + ## Proxy Support ```java diff --git a/client/src/main/java/org/asynchttpclient/Realm.java b/client/src/main/java/org/asynchttpclient/Realm.java index cf770dafe..46e1d7aeb 100644 --- a/client/src/main/java/org/asynchttpclient/Realm.java +++ b/client/src/main/java/org/asynchttpclient/Realm.java @@ -221,6 +221,9 @@ public boolean isOmitQuery() { return servicePrincipalName; } + /** + * Returns whether SPNEGO/Kerberos authentication canonicalizes the target hostname through the JVM resolver. + */ public boolean isUseCanonicalHostname() { return useCanonicalHostname; } @@ -421,6 +424,11 @@ public Builder setServicePrincipalName(@Nullable String servicePrincipalName) { return this; } + /** + * Enables JVM canonical-hostname resolution when deriving the SPNEGO/Kerberos service principal name. + * Resolution is blocking and can run on a Netty event-loop thread during authentication retries. Prefer + * {@link #setServicePrincipalName(String)} when the service principal name is known. + */ public Builder setUseCanonicalHostname(boolean useCanonicalHostname) { this.useCanonicalHostname = useCanonicalHostname; return this;