Skip to content

Commit 844933a

Browse files
authored
Merge pull request #1645 from marklogic/feature/4126-oauth
MLE-4126 Can now configure OAuth authentication
2 parents 65b0e7e + 6946d38 commit 844933a

File tree

10 files changed

+106
-4
lines changed

10 files changed

+106
-4
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/DatabaseClientBuilder.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class DatabaseClientBuilder {
4444
public final static String AUTH_TYPE_KERBEROS = "kerberos";
4545
public final static String AUTH_TYPE_CERTIFICATE = "certificate";
4646
public final static String AUTH_TYPE_SAML = "saml";
47+
public final static String AUTH_TYPE_OAUTH = "oauth";
4748

4849
private final Map<String, Object> props;
4950

@@ -189,6 +190,25 @@ public DatabaseClientBuilder withSAMLAuth(String token) {
189190
.withSAMLToken(token);
190191
}
191192

193+
/**
194+
* @param token
195+
* @return
196+
* @since 6.6.0
197+
*/
198+
public DatabaseClientBuilder withOAuth(String token) {
199+
return withAuthType(AUTH_TYPE_OAUTH).withOAuthToken(token);
200+
}
201+
202+
/**
203+
* @param token
204+
* @return
205+
* @since 6.6.0
206+
*/
207+
public DatabaseClientBuilder withOAuthToken(String token) {
208+
props.put(PREFIX + "oauth.token", token);
209+
return this;
210+
}
211+
192212
public DatabaseClientBuilder withConnectionType(DatabaseClient.ConnectionType type) {
193213
props.put(PREFIX + "connectionType", type);
194214
return this;

marklogic-client-api/src/main/java/com/marklogic/client/DatabaseClientFactory.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,24 @@ public MarkLogicCloudAuthContext withSSLHostnameVerifier(SSLHostnameVerifier ver
529529
}
530530
}
531531

532+
/**
533+
* @since 6.6.0
534+
*/
535+
public static class OAuthContext extends AuthContext {
536+
private String token;
537+
538+
/**
539+
* @param token the OAuth token to include in the Authorization header in each request sent to MarkLogic.
540+
*/
541+
public OAuthContext(String token) {
542+
this.token = token;
543+
}
544+
545+
public String getToken() {
546+
return token;
547+
}
548+
}
549+
532550
public static class BasicAuthContext extends AuthContext {
533551
String user;
534552
String password;
@@ -1287,6 +1305,7 @@ public String getCertificatePassword() {
12871305
* minutes for which an access token lasts; supported since 6.3.0.</li>
12881306
* <li>marklogic.client.kerberos.principal = must be a String; required for Kerberos authentication</li>
12891307
* <li>marklogic.client.saml.token = must be a String; required for SAML authentication</li>
1308+
* <li>marklogic.client.oauth.token = must be a String; required for OAuth authentication; supported since 6.6.0.</li>
12901309
* <li>marklogic.client.sslContext = must be an instance of {@code javax.net.ssl.SSLContext}</li>
12911310
* <li>marklogic.client.sslProtocol = must be a String; if "default', then uses the JVM default SSL
12921311
* context; else, the value is passed to the {@code getInstance} method in {@code javax.net.ssl.SSLContext}</li>

marklogic-client-api/src/main/java/com/marklogic/client/impl/DatabaseClientPropertySource.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ private DatabaseClientFactory.SecurityContext newSecurityContext(String type, SS
175175
return newCertificateAuthContext(sslInputs);
176176
case DatabaseClientBuilder.AUTH_TYPE_SAML:
177177
return newSAMLAuthContext();
178+
case DatabaseClientBuilder.AUTH_TYPE_OAUTH:
179+
return newOAuthContext();
178180
default:
179181
throw new IllegalArgumentException("Unrecognized auth type: " + type);
180182
}
@@ -253,6 +255,10 @@ private DatabaseClientFactory.SecurityContext newSAMLAuthContext() {
253255
return new DatabaseClientFactory.SAMLAuthContext(getRequiredStringValue("saml.token"));
254256
}
255257

258+
private DatabaseClientFactory.SecurityContext newOAuthContext() {
259+
return new DatabaseClientFactory.OAuthContext(getRequiredStringValue("oauth.token"));
260+
}
261+
256262
private DatabaseClientFactory.SSLHostnameVerifier determineHostnameVerifier() {
257263
Object verifierObject = propertySource.apply(PREFIX + "sslHostnameVerifier");
258264
if (verifierObject instanceof DatabaseClientFactory.SSLHostnameVerifier) {

marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/BasicAuthenticationConfigurer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import java.io.IOException;
2626
import java.nio.charset.Charset;
2727

28-
public class BasicAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.BasicAuthContext> {
28+
class BasicAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.BasicAuthContext> {
2929

3030
@Override
3131
public void configureAuthentication(OkHttpClient.Builder clientBuilder, DatabaseClientFactory.BasicAuthContext securityContext) {

marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/DigestAuthenticationConfigurer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import java.util.Map;
2727
import java.util.concurrent.ConcurrentHashMap;
2828

29-
public class DigestAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.DigestAuthContext> {
29+
class DigestAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.DigestAuthContext> {
3030

3131
@Override
3232
public void configureAuthentication(OkHttpClient.Builder clientBuilder, DatabaseClientFactory.DigestAuthContext securityContext) {

marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/MarkLogicCloudAuthenticationConfigurer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@
3030

3131
import java.io.IOException;
3232

33-
public class MarkLogicCloudAuthenticationConfigurer implements AuthenticationConfigurer<MarkLogicCloudAuthContext> {
33+
class MarkLogicCloudAuthenticationConfigurer implements AuthenticationConfigurer<MarkLogicCloudAuthContext> {
3434

3535
private String host;
3636

37-
public MarkLogicCloudAuthenticationConfigurer(String host) {
37+
MarkLogicCloudAuthenticationConfigurer(String host) {
3838
this.host = host;
3939
}
4040

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.marklogic.client.impl.okhttp;
2+
3+
import com.marklogic.client.DatabaseClientFactory;
4+
import okhttp3.OkHttpClient;
5+
import okhttp3.Request;
6+
7+
/**
8+
* @since 6.6.0
9+
*/
10+
class OAuthAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.OAuthContext> {
11+
12+
@Override
13+
public void configureAuthentication(OkHttpClient.Builder clientBuilder, DatabaseClientFactory.OAuthContext authContext) {
14+
clientBuilder.addInterceptor(chain -> {
15+
Request authenticatedRequest = makeAuthenticatedRequest(chain.request(), authContext);
16+
return chain.proceed(authenticatedRequest);
17+
});
18+
}
19+
20+
Request makeAuthenticatedRequest(Request request, DatabaseClientFactory.OAuthContext authContext) {
21+
String authValue = String.format("Bearer %s", authContext.getToken());
22+
return request.newBuilder().header("Authorization", authValue).build();
23+
}
24+
}
25+

marklogic-client-api/src/main/java/com/marklogic/client/impl/okhttp/OkHttpUtil.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public static OkHttpClient.Builder newOkHttpClientBuilder(String host, DatabaseC
6868
configureSAMLAuth((DatabaseClientFactory.SAMLAuthContext) securityContext, clientBuilder);
6969
} else if (securityContext instanceof DatabaseClientFactory.MarkLogicCloudAuthContext) {
7070
authenticationConfigurer = new MarkLogicCloudAuthenticationConfigurer(host);
71+
} else if (securityContext instanceof DatabaseClientFactory.OAuthContext) {
72+
authenticationConfigurer = new OAuthAuthenticationConfigurer();
7173
} else {
7274
throw new IllegalArgumentException("Unsupported security context: " + securityContext.getClass());
7375
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.marklogic.client.impl.okhttp;
2+
3+
import com.marklogic.client.DatabaseClientFactory;
4+
import okhttp3.Request;
5+
import okhttp3.mockwebserver.MockWebServer;
6+
import org.junit.jupiter.api.Test;
7+
8+
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
10+
public class OAuthAuthenticationConfigurerTest {
11+
12+
@Test
13+
void test() {
14+
DatabaseClientFactory.OAuthContext authContext = new DatabaseClientFactory.OAuthContext("abc123");
15+
Request request = new Request.Builder().url(new MockWebServer().url("/url-doesnt-matter")).build();
16+
17+
Request authenticatedRequest = new OAuthAuthenticationConfigurer().makeAuthenticatedRequest(request, authContext);
18+
assertEquals("Bearer abc123", authenticatedRequest.header("Authorization"));
19+
}
20+
}

marklogic-client-api/src/test/java/com/marklogic/client/test/DatabaseClientBuilderTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,16 @@ void saml() {
204204
assertEquals("my-token", context.getToken());
205205
}
206206

207+
@Test
208+
void oauth() {
209+
bean = Common.newClientBuilder()
210+
.withOAuth("abc123")
211+
.buildBean();
212+
213+
DatabaseClientFactory.OAuthContext context = (DatabaseClientFactory.OAuthContext) bean.getSecurityContext();
214+
assertEquals("abc123", context.getToken());
215+
}
216+
207217
@Test
208218
void defaultSslContext() throws Exception {
209219
bean = Common.newClientBuilder()

0 commit comments

Comments
 (0)