diff --git a/CHANGES.txt b/CHANGES.txt
index 072fab1f..fe88db4a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,6 @@
+4.13.0 (Sep 6, 2024)
+- Added support for Kerberos Proxy authentication.
+
4.12.1 (Jun 10, 2024)
- Fixed deadlock for virtual thread in Push Manager and SSE Client.
diff --git a/client/pom.xml b/client/pom.xml
index 8e7ac11c..0fb3f854 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -181,11 +181,13 @@
com.squareup.okhttp3
okhttp
4.12.0
+ true
com.squareup.okhttp3
logging-interceptor
4.12.0
+ true
diff --git a/client/src/main/java/io/split/client/SplitClientConfig.java b/client/src/main/java/io/split/client/SplitClientConfig.java
index 6f8db64c..0a6b0fbd 100644
--- a/client/src/main/java/io/split/client/SplitClientConfig.java
+++ b/client/src/main/java/io/split/client/SplitClientConfig.java
@@ -4,9 +4,9 @@
import io.split.client.impressions.ImpressionsManager;
import io.split.client.utils.FileTypeEnum;
import io.split.integrations.IntegrationsConfig;
+import io.split.service.ProxyAuthScheme;
import io.split.storages.enums.OperationMode;
import io.split.storages.enums.StorageMode;
-import io.split.service.HttpAuthScheme;
import org.apache.hc.core5.http.HttpHost;
import pluggable.CustomStorageWrapper;
@@ -92,9 +92,8 @@ public class SplitClientConfig {
private final HashSet _flagSetsFilter;
private final int _invalidSets;
private final CustomHeaderDecorator _customHeaderDecorator;
- private final HttpAuthScheme _authScheme;
- private final String _kerberosPrincipalName;
-
+ private final ProxyAuthScheme _proxyAuthScheme;
+ private final String _proxyKerberosPrincipalName;
public static Builder builder() {
return new Builder();
@@ -152,8 +151,8 @@ private SplitClientConfig(String endpoint,
HashSet flagSetsFilter,
int invalidSets,
CustomHeaderDecorator customHeaderDecorator,
- HttpAuthScheme authScheme,
- String kerberosPrincipalName) {
+ ProxyAuthScheme proxyAuthScheme,
+ String proxyKerberosPrincipalName) {
_endpoint = endpoint;
_eventsEndpoint = eventsEndpoint;
_featuresRefreshRate = pollForFeatureChangesEveryNSeconds;
@@ -206,8 +205,8 @@ private SplitClientConfig(String endpoint,
_flagSetsFilter = flagSetsFilter;
_invalidSets = invalidSets;
_customHeaderDecorator = customHeaderDecorator;
- _authScheme = authScheme;
- _kerberosPrincipalName = kerberosPrincipalName;
+ _proxyAuthScheme = proxyAuthScheme;
+ _proxyKerberosPrincipalName = proxyKerberosPrincipalName;
Properties props = new Properties();
try {
@@ -415,10 +414,10 @@ public int getInvalidSets() {
public CustomHeaderDecorator customHeaderDecorator() {
return _customHeaderDecorator;
}
- public HttpAuthScheme authScheme() {
- return _authScheme;
+ public ProxyAuthScheme proxyAuthScheme() {
+ return _proxyAuthScheme;
}
- public String kerberosPrincipalName() { return _kerberosPrincipalName; }
+ public String proxyKerberosPrincipalName() { return _proxyKerberosPrincipalName; }
public static final class Builder {
@@ -477,8 +476,8 @@ public static final class Builder {
private HashSet _flagSetsFilter = new HashSet<>();
private int _invalidSetsCount = 0;
private CustomHeaderDecorator _customHeaderDecorator = null;
- private HttpAuthScheme _authScheme = null;
- private String _kerberosPrincipalName = null;
+ private ProxyAuthScheme _proxyAuthScheme = null;
+ private String _proxyKerberosPrincipalName = null;
public Builder() {
}
@@ -976,22 +975,22 @@ public Builder customHeaderDecorator(CustomHeaderDecorator customHeaderDecorator
/**
* Authentication Scheme
*
- * @param authScheme
+ * @param proxyAuthScheme
* @return this builder
*/
- public Builder authScheme(HttpAuthScheme authScheme) {
- _authScheme = authScheme;
+ public Builder proxyAuthScheme(ProxyAuthScheme proxyAuthScheme) {
+ _proxyAuthScheme = proxyAuthScheme;
return this;
}
/**
* Kerberos Principal Account Name
*
- * @param kerberosPrincipalName
+ * @param proxyKerberosPrincipalName
* @return this builder
*/
- public Builder kerberosPrincipalName(String kerberosPrincipalName) {
- _kerberosPrincipalName = kerberosPrincipalName;
+ public Builder proxyKerberosPrincipalName(String proxyKerberosPrincipalName) {
+ _proxyKerberosPrincipalName = proxyKerberosPrincipalName;
return this;
}
@@ -1054,11 +1053,11 @@ private void verifyEndPoints() {
}
private void verifyAuthScheme() {
- if (_authScheme == HttpAuthScheme.KERBEROS) {
+ if (_proxyAuthScheme == ProxyAuthScheme.KERBEROS) {
if (proxy() == null) {
throw new IllegalStateException("Kerberos mode require Proxy parameters.");
}
- if (_kerberosPrincipalName == null) {
+ if (_proxyKerberosPrincipalName == null) {
throw new IllegalStateException("Kerberos mode require Kerberos Principal Name.");
}
}
@@ -1184,8 +1183,8 @@ public SplitClientConfig build() {
_flagSetsFilter,
_invalidSetsCount,
_customHeaderDecorator,
- _authScheme,
- _kerberosPrincipalName);
+ _proxyAuthScheme,
+ _proxyKerberosPrincipalName);
}
}
}
\ No newline at end of file
diff --git a/client/src/main/java/io/split/client/SplitFactoryImpl.java b/client/src/main/java/io/split/client/SplitFactoryImpl.java
index e43d1404..32568342 100644
--- a/client/src/main/java/io/split/client/SplitFactoryImpl.java
+++ b/client/src/main/java/io/split/client/SplitFactoryImpl.java
@@ -57,10 +57,10 @@
import io.split.engine.segments.SegmentChangeFetcher;
import io.split.engine.segments.SegmentSynchronizationTaskImp;
import io.split.integrations.IntegrationsConfig;
-import io.split.service.HttpAuthScheme;
-import io.split.service.SplitHttpClient;
-import io.split.service.SplitHttpClientImpl;
+import io.split.service.ProxyAuthScheme;
import io.split.service.SplitHttpClientKerberosImpl;
+import io.split.service.SplitHttpClientImpl;
+import io.split.service.SplitHttpClient;
import io.split.service.HTTPKerberosAuthInterceptor;
import io.split.storages.SegmentCache;
import io.split.storages.SegmentCacheConsumer;
@@ -507,7 +507,7 @@ protected static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClie
SDKMetadata sdkMetadata, RequestDecorator requestDecorator)
throws URISyntaxException, IOException {
// setup Kerberos client
- if (config.authScheme() == HttpAuthScheme.KERBEROS) {
+ if (config.proxyAuthScheme() == ProxyAuthScheme.KERBEROS) {
_log.info("Using Kerberos-Proxy Authentication Scheme.");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.proxy().getHostName(), config.proxy().getPort()));
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
@@ -583,7 +583,7 @@ protected static OkHttpClient buildOkHttpClient(Proxy proxy, SplitClientConfig c
protected static HTTPKerberosAuthInterceptor getProxyAuthenticator(SplitClientConfig config,
Map kerberosOptions) throws IOException {
- return new HTTPKerberosAuthInterceptor(config.kerberosPrincipalName(), kerberosOptions);
+ return new HTTPKerberosAuthInterceptor(config.proxyKerberosPrincipalName(), kerberosOptions);
}
private static CloseableHttpClient buildSSEdHttpClient(String apiToken, SplitClientConfig config,
SDKMetadata sdkMetadata) {
diff --git a/client/src/main/java/io/split/service/HTTPKerberosAuthInterceptor.java b/client/src/main/java/io/split/service/HTTPKerberosAuthInterceptor.java
index 34fe0eaa..038425c1 100644
--- a/client/src/main/java/io/split/service/HTTPKerberosAuthInterceptor.java
+++ b/client/src/main/java/io/split/service/HTTPKerberosAuthInterceptor.java
@@ -31,10 +31,25 @@
import okhttp3.Route;
/**
+ *
* An HTTP Request interceptor that modifies the request headers to enable
* Kerberos authentication. It appends the Kerberos authentication token to the
* 'Authorization' request header for Kerberos authentication
*
+ * Copyright 2024 MarkLogic Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
*/
public class HTTPKerberosAuthInterceptor implements Authenticator {
String host;
diff --git a/client/src/main/java/io/split/service/HttpAuthScheme.java b/client/src/main/java/io/split/service/ProxyAuthScheme.java
similarity index 58%
rename from client/src/main/java/io/split/service/HttpAuthScheme.java
rename to client/src/main/java/io/split/service/ProxyAuthScheme.java
index 1753f736..1d4c237b 100644
--- a/client/src/main/java/io/split/service/HttpAuthScheme.java
+++ b/client/src/main/java/io/split/service/ProxyAuthScheme.java
@@ -1,5 +1,5 @@
package io.split.service;
-public enum HttpAuthScheme {
+public enum ProxyAuthScheme {
KERBEROS
}
diff --git a/client/src/test/java/io/split/client/SplitClientConfigTest.java b/client/src/test/java/io/split/client/SplitClientConfigTest.java
index 760479d8..c79e6118 100644
--- a/client/src/test/java/io/split/client/SplitClientConfigTest.java
+++ b/client/src/test/java/io/split/client/SplitClientConfigTest.java
@@ -6,7 +6,7 @@
import io.split.client.impressions.ImpressionsManager;
import io.split.client.dtos.RequestContext;
import io.split.integrations.IntegrationsConfig;
-import io.split.service.HttpAuthScheme;
+import io.split.service.ProxyAuthScheme;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
@@ -259,30 +259,30 @@ public Map> getHeaderOverrides(RequestContext context) {
@Test
public void checkExpectedAuthScheme() {
SplitClientConfig cfg = SplitClientConfig.builder()
- .authScheme(HttpAuthScheme.KERBEROS)
- .kerberosPrincipalName("bilal@bilal")
+ .proxyAuthScheme(ProxyAuthScheme.KERBEROS)
+ .proxyKerberosPrincipalName("bilal@bilal")
.proxyHost("local")
.proxyPort(8080)
.build();
- Assert.assertEquals(HttpAuthScheme.KERBEROS, cfg.authScheme());
+ Assert.assertEquals(ProxyAuthScheme.KERBEROS, cfg.proxyAuthScheme());
cfg = SplitClientConfig.builder()
.build();
- Assert.assertEquals(null, cfg.authScheme());
+ Assert.assertEquals(null, cfg.proxyAuthScheme());
}
@Test(expected = IllegalStateException.class)
public void testAuthSchemeWithoutProxy() {
SplitClientConfig.builder()
- .authScheme(HttpAuthScheme.KERBEROS)
- .kerberosPrincipalName("bilal")
+ .proxyAuthScheme(ProxyAuthScheme.KERBEROS)
+ .proxyKerberosPrincipalName("bilal")
.build();
}
@Test(expected = IllegalStateException.class)
public void testAuthSchemeWithoutPrincipalName() {
SplitClientConfig.builder()
- .authScheme(HttpAuthScheme.KERBEROS)
+ .proxyAuthScheme(ProxyAuthScheme.KERBEROS)
.proxyHost("local")
.proxyPort(8080)
.build();
diff --git a/client/src/test/java/io/split/client/SplitFactoryImplTest.java b/client/src/test/java/io/split/client/SplitFactoryImplTest.java
index f5ae83d0..ab775553 100644
--- a/client/src/test/java/io/split/client/SplitFactoryImplTest.java
+++ b/client/src/test/java/io/split/client/SplitFactoryImplTest.java
@@ -4,7 +4,7 @@
import io.split.client.utils.FileTypeEnum;
import io.split.client.utils.SDKMetadata;
import io.split.integrations.IntegrationsConfig;
-import io.split.service.HttpAuthScheme;
+import io.split.service.ProxyAuthScheme;
import io.split.service.SplitHttpClient;
import io.split.service.SplitHttpClientKerberosImpl;
import io.split.storages.enums.OperationMode;
@@ -380,8 +380,8 @@ public void testBuildKerberosClientParams() throws URISyntaxException, IOExcepti
SplitClientConfig splitClientConfig = SplitClientConfig.builder()
.setBlockUntilReadyTimeout(10000)
- .authScheme(HttpAuthScheme.KERBEROS)
- .kerberosPrincipalName("bilal@localhost")
+ .proxyAuthScheme(ProxyAuthScheme.KERBEROS)
+ .proxyKerberosPrincipalName("bilal@localhost")
.proxyPort(6060)
.proxyHost(ENDPOINT)
.build();
@@ -422,8 +422,8 @@ public void testFactoryKerberosInstance() throws URISyntaxException, IOException
SplitClientConfig splitClientConfig = SplitClientConfig.builder()
.setBlockUntilReadyTimeout(10000)
- .authScheme(HttpAuthScheme.KERBEROS)
- .kerberosPrincipalName("bilal@localhost")
+ .proxyAuthScheme(ProxyAuthScheme.KERBEROS)
+ .proxyKerberosPrincipalName("bilal@localhost")
.proxyPort(6060)
.proxyHost(ENDPOINT)
.build();
@@ -447,8 +447,8 @@ public void testFactoryKerberosInstance() throws URISyntaxException, IOException
public void testBuildOkHttpClient() {
SplitClientConfig splitClientConfig = SplitClientConfig.builder()
.setBlockUntilReadyTimeout(10000)
- .authScheme(HttpAuthScheme.KERBEROS)
- .kerberosPrincipalName("bilal@localhost")
+ .proxyAuthScheme(ProxyAuthScheme.KERBEROS)
+ .proxyKerberosPrincipalName("bilal@localhost")
.proxyPort(6060)
.proxyHost(ENDPOINT)
.build();
diff --git a/client/src/test/java/io/split/service/HTTPKerberosAuthIntercepterTest.java b/client/src/test/java/io/split/service/HTTPKerberosAuthIntercepterTest.java
index 62bc453e..b49eda75 100644
--- a/client/src/test/java/io/split/service/HTTPKerberosAuthIntercepterTest.java
+++ b/client/src/test/java/io/split/service/HTTPKerberosAuthIntercepterTest.java
@@ -25,7 +25,6 @@
import java.util.HashMap;
import java.util.Map;
-
@RunWith(PowerMockRunner.class)
@PrepareForTest(HTTPKerberosAuthInterceptor.class)
public class HTTPKerberosAuthIntercepterTest {