fix: handle HTTPS redirects in InsecureTlsHelper for OIDC discovery
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m13s
CI / docker (push) Successful in 42s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 38s

Java's automatic redirect following creates new connections that do NOT
inherit custom SSLSocketFactory/HostnameVerifier. This caused the OIDC
discovery fetch to fail on redirect even with TLS_SKIP_VERIFY=true.
Now disables auto-redirect and follows manually with SSL on each hop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-06 00:51:49 +02:00
parent 083cb8b9ec
commit 99e2a8354f
2 changed files with 30 additions and 5 deletions

View File

@@ -10,6 +10,8 @@ import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
@@ -59,13 +61,33 @@ final class InsecureTlsHelper {
/**
* Opens an {@link InputStream} from the given URL, applying trust-all TLS
* if the connection is HTTPS and {@code skipVerify} is true.
* <p>
* Handles redirects manually because Java's automatic redirect following
* creates new connections that do NOT inherit custom SSLSocketFactory /
* HostnameVerifier settings.
*/
static InputStream openStream(URL url, boolean skipVerify) throws Exception {
URLConnection conn = url.openConnection();
if (skipVerify && conn instanceof HttpsURLConnection https) {
https.setSSLSocketFactory(socketFactory());
https.setHostnameVerifier(hostnameVerifier());
URL current = url;
for (int i = 0; i < 5; i++) {
HttpURLConnection conn = (HttpURLConnection) current.openConnection();
if (skipVerify && conn instanceof HttpsURLConnection https) {
https.setSSLSocketFactory(socketFactory());
https.setHostnameVerifier(hostnameVerifier());
}
conn.setInstanceFollowRedirects(false);
int code = conn.getResponseCode();
if (code >= 300 && code < 400) {
String location = conn.getHeaderField("Location");
conn.disconnect();
if (location == null) {
throw new java.io.IOException("Redirect with no Location header from " + current);
}
current = new URI(location).toURL();
log.debug("Following OIDC redirect -> {}", current);
continue;
}
return conn.getInputStream();
}
return conn.getInputStream();
throw new java.io.IOException("Too many redirects from " + url);
}
}

View File

@@ -61,6 +61,9 @@ public class OidcTokenExchanger {
SecurityProperties securityProperties) {
this.configRepository = configRepository;
this.tlsSkipVerify = securityProperties.isOidcTlsSkipVerify();
if (tlsSkipVerify) {
log.warn("OIDC TLS skip-verify enabled for token exchanger");
}
}
public record OidcUserInfo(String subject, String email, String name, List<String> roles, String idToken) {}