fix: handle HTTPS redirects in InsecureTlsHelper for OIDC discovery
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:
@@ -10,6 +10,8 @@ import javax.net.ssl.SSLSocketFactory;
|
|||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@@ -59,13 +61,33 @@ final class InsecureTlsHelper {
|
|||||||
/**
|
/**
|
||||||
* Opens an {@link InputStream} from the given URL, applying trust-all TLS
|
* Opens an {@link InputStream} from the given URL, applying trust-all TLS
|
||||||
* if the connection is HTTPS and {@code skipVerify} is true.
|
* 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 {
|
static InputStream openStream(URL url, boolean skipVerify) throws Exception {
|
||||||
URLConnection conn = url.openConnection();
|
URL current = url;
|
||||||
if (skipVerify && conn instanceof HttpsURLConnection https) {
|
for (int i = 0; i < 5; i++) {
|
||||||
https.setSSLSocketFactory(socketFactory());
|
HttpURLConnection conn = (HttpURLConnection) current.openConnection();
|
||||||
https.setHostnameVerifier(hostnameVerifier());
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ public class OidcTokenExchanger {
|
|||||||
SecurityProperties securityProperties) {
|
SecurityProperties securityProperties) {
|
||||||
this.configRepository = configRepository;
|
this.configRepository = configRepository;
|
||||||
this.tlsSkipVerify = securityProperties.isOidcTlsSkipVerify();
|
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) {}
|
public record OidcUserInfo(String subject, String email, String name, List<String> roles, String idToken) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user