Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class DatabaseClientBuilder {
public final static String AUTH_TYPE_KERBEROS = "kerberos";
public final static String AUTH_TYPE_CERTIFICATE = "certificate";
public final static String AUTH_TYPE_SAML = "saml";
public final static String AUTH_TYPE_OAUTH = "oauth";

private final Map<String, Object> props;

Expand Down Expand Up @@ -189,6 +190,25 @@ public DatabaseClientBuilder withSAMLAuth(String token) {
.withSAMLToken(token);
}

/**
* @param token
* @return
* @since 6.6.0
*/
public DatabaseClientBuilder withOAuth(String token) {
return withAuthType(AUTH_TYPE_OAUTH).withOAuthToken(token);
}

/**
* @param token
* @return
* @since 6.6.0
*/
public DatabaseClientBuilder withOAuthToken(String token) {
props.put(PREFIX + "oauth.token", token);
return this;
}

public DatabaseClientBuilder withConnectionType(DatabaseClient.ConnectionType type) {
props.put(PREFIX + "connectionType", type);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,24 @@ public MarkLogicCloudAuthContext withSSLHostnameVerifier(SSLHostnameVerifier ver
}
}

/**
* @since 6.6.0
*/
public static class OAuthContext extends AuthContext {
private String token;

/**
* @param token the OAuth token to include in the Authorization header in each request sent to MarkLogic.
*/
public OAuthContext(String token) {
this.token = token;
}

public String getToken() {
return token;
}
}

public static class BasicAuthContext extends AuthContext {
String user;
String password;
Expand Down Expand Up @@ -1287,6 +1305,7 @@ public String getCertificatePassword() {
* minutes for which an access token lasts; supported since 6.3.0.</li>
* <li>marklogic.client.kerberos.principal = must be a String; required for Kerberos authentication</li>
* <li>marklogic.client.saml.token = must be a String; required for SAML authentication</li>
* <li>marklogic.client.oauth.token = must be a String; required for OAuth authentication; supported since 6.6.0.</li>
* <li>marklogic.client.sslContext = must be an instance of {@code javax.net.ssl.SSLContext}</li>
* <li>marklogic.client.sslProtocol = must be a String; if "default', then uses the JVM default SSL
* context; else, the value is passed to the {@code getInstance} method in {@code javax.net.ssl.SSLContext}</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ private DatabaseClientFactory.SecurityContext newSecurityContext(String type, SS
return newCertificateAuthContext(sslInputs);
case DatabaseClientBuilder.AUTH_TYPE_SAML:
return newSAMLAuthContext();
case DatabaseClientBuilder.AUTH_TYPE_OAUTH:
return newOAuthContext();
default:
throw new IllegalArgumentException("Unrecognized auth type: " + type);
}
Expand Down Expand Up @@ -253,6 +255,10 @@ private DatabaseClientFactory.SecurityContext newSAMLAuthContext() {
return new DatabaseClientFactory.SAMLAuthContext(getRequiredStringValue("saml.token"));
}

private DatabaseClientFactory.SecurityContext newOAuthContext() {
return new DatabaseClientFactory.OAuthContext(getRequiredStringValue("oauth.token"));
}

private DatabaseClientFactory.SSLHostnameVerifier determineHostnameVerifier() {
Object verifierObject = propertySource.apply(PREFIX + "sslHostnameVerifier");
if (verifierObject instanceof DatabaseClientFactory.SSLHostnameVerifier) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import java.io.IOException;
import java.nio.charset.Charset;

public class BasicAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.BasicAuthContext> {
class BasicAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.BasicAuthContext> {

@Override
public void configureAuthentication(OkHttpClient.Builder clientBuilder, DatabaseClientFactory.BasicAuthContext securityContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class DigestAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.DigestAuthContext> {
class DigestAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.DigestAuthContext> {

@Override
public void configureAuthentication(OkHttpClient.Builder clientBuilder, DatabaseClientFactory.DigestAuthContext securityContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@

import java.io.IOException;

public class MarkLogicCloudAuthenticationConfigurer implements AuthenticationConfigurer<MarkLogicCloudAuthContext> {
class MarkLogicCloudAuthenticationConfigurer implements AuthenticationConfigurer<MarkLogicCloudAuthContext> {

private String host;

public MarkLogicCloudAuthenticationConfigurer(String host) {
MarkLogicCloudAuthenticationConfigurer(String host) {
this.host = host;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.marklogic.client.impl.okhttp;

import com.marklogic.client.DatabaseClientFactory;
import okhttp3.OkHttpClient;
import okhttp3.Request;

/**
* @since 6.6.0
*/
class OAuthAuthenticationConfigurer implements AuthenticationConfigurer<DatabaseClientFactory.OAuthContext> {

@Override
public void configureAuthentication(OkHttpClient.Builder clientBuilder, DatabaseClientFactory.OAuthContext authContext) {
clientBuilder.addInterceptor(chain -> {
Request authenticatedRequest = makeAuthenticatedRequest(chain.request(), authContext);
return chain.proceed(authenticatedRequest);
});
}

Request makeAuthenticatedRequest(Request request, DatabaseClientFactory.OAuthContext authContext) {
String authValue = String.format("Bearer %s", authContext.getToken());
return request.newBuilder().header("Authorization", authValue).build();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public static OkHttpClient.Builder newOkHttpClientBuilder(String host, DatabaseC
configureSAMLAuth((DatabaseClientFactory.SAMLAuthContext) securityContext, clientBuilder);
} else if (securityContext instanceof DatabaseClientFactory.MarkLogicCloudAuthContext) {
authenticationConfigurer = new MarkLogicCloudAuthenticationConfigurer(host);
} else if (securityContext instanceof DatabaseClientFactory.OAuthContext) {
authenticationConfigurer = new OAuthAuthenticationConfigurer();
} else {
throw new IllegalArgumentException("Unsupported security context: " + securityContext.getClass());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.marklogic.client.impl.okhttp;

import com.marklogic.client.DatabaseClientFactory;
import okhttp3.Request;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class OAuthAuthenticationConfigurerTest {

@Test
void test() {
DatabaseClientFactory.OAuthContext authContext = new DatabaseClientFactory.OAuthContext("abc123");
Request request = new Request.Builder().url(new MockWebServer().url("/url-doesnt-matter")).build();

Request authenticatedRequest = new OAuthAuthenticationConfigurer().makeAuthenticatedRequest(request, authContext);
assertEquals("Bearer abc123", authenticatedRequest.header("Authorization"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,16 @@ void saml() {
assertEquals("my-token", context.getToken());
}

@Test
void oauth() {
bean = Common.newClientBuilder()
.withOAuth("abc123")
.buildBean();

DatabaseClientFactory.OAuthContext context = (DatabaseClientFactory.OAuthContext) bean.getSecurityContext();
assertEquals("abc123", context.getToken());
}

@Test
void defaultSslContext() throws Exception {
bean = Common.newClientBuilder()
Expand Down