Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 2234d44

Browse files
authored
Merge pull request #467 from marklogic-community/feature/174-all-auth-types
DEVEXP-174: Now supporting cert/kerberos/saml auth
2 parents 5d1e6cc + f25a442 commit 2234d44

File tree

8 files changed

+205
-16
lines changed

8 files changed

+205
-16
lines changed

src/main/java/com/marklogic/appdeployer/DefaultAppConfigFactory.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ public void initialize() {
213213
config.setAppServicesSecurityContextType(SecurityContextType.valueOf(prop.toUpperCase()));
214214
});
215215
propertyConsumerMap.put("mlAppServicesCertFile", (config, prop) -> {
216-
logger.info("App Services cert file: " + prop);
216+
logger.info("App Services certificate file: " + prop);
217217
config.setAppServicesCertFile(prop);
218218
});
219219
propertyConsumerMap.put("mlAppServicesCertPassword", (config, prop) -> {
@@ -228,7 +228,6 @@ public void initialize() {
228228
config.setAppServicesExternalName(prop);
229229
});
230230
propertyConsumerMap.put("mlAppServicesSamlToken", (config, prop) -> {
231-
logger.info("App Services SAML token: " + prop);
232231
config.setAppServicesSamlToken(prop);
233232
});
234233

@@ -307,19 +306,17 @@ public void initialize() {
307306
config.setRestSecurityContextType(SecurityContextType.valueOf(prop.toUpperCase()));
308307
});
309308
propertyConsumerMap.put("mlRestCertFile", (config, prop) -> {
310-
logger.info("REST cert file: " + prop);
309+
logger.info("REST certificate file: " + prop);
311310
config.setRestCertFile(prop);
312311
});
313312
propertyConsumerMap.put("mlRestCertPassword", (config, prop) -> {
314-
logger.info("REST cert password: " + prop);
315313
config.setRestCertPassword(prop);
316314
});
317315
propertyConsumerMap.put("mlRestExternalName", (config, prop) -> {
318316
logger.info("REST external name: " + prop);
319317
config.setRestExternalName(prop);
320318
});
321319
propertyConsumerMap.put("mlRestSamlToken", (config, prop) -> {
322-
logger.info("REST SAML token: " + prop);
323320
config.setRestSamlToken(prop);
324321
});
325322
propertyConsumerMap.put("mlRestBasePath", (config, prop) -> {

src/main/java/com/marklogic/mgmt/DefaultManageConfigFactory.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public void initialize() {
4343
config.setPort(Integer.parseInt(prop));
4444
});
4545

46+
propertyConsumerMap.put("mlManageAuthentication", (config, prop) -> {
47+
logger.info("Manage authentication: " + prop);
48+
config.setSecurityContextType(prop);
49+
});
50+
4651
propertyConsumerMap.put("mlManageUsername", (config, prop) -> {
4752
logger.info("Manage username: " + prop);
4853
config.setUsername(prop);
@@ -72,6 +77,21 @@ public void initialize() {
7277
}
7378
});
7479

80+
propertyConsumerMap.put("mlManageCertFile", (config, prop) -> {
81+
logger.info("Manage certificate file: " + prop);
82+
config.setCertFile(prop);
83+
});
84+
propertyConsumerMap.put("mlManageCertPassword", (config, prop) -> {
85+
config.setCertPassword(prop);
86+
});
87+
propertyConsumerMap.put("mlManageExternalName", (config, prop) -> {
88+
logger.info("Manage external name: " + prop);
89+
config.setExternalName(prop);
90+
});
91+
propertyConsumerMap.put("mlManageSamlToken", (config, prop) -> {
92+
config.setSamlToken(prop);
93+
});
94+
7595
propertyConsumerMap.put("mlManageBasePath", (config, prop) -> {
7696
logger.info("Manage base path: " + prop);
7797
config.setBasePath(prop);

src/main/java/com/marklogic/mgmt/ManageClient.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ public void setManageConfig(ManageConfig config) {
6363
}
6464

6565
RestConfig rc = new RestConfig(config);
66-
// Override settings based on the 3 "security user"-specific properties known by ManageConfig
66+
// Override settings based on the 3 "security user"-specific properties known by ManageConfig.
67+
// Note that in 4.5.0, with the addition of cloud/certificate/kerberos/saml auth, this will only have any
68+
// impact if the user is using digest or basic auth. There's no equivalent of a separate "security" user
69+
// yet for the other 4 authentication types.
6770
rc.setUsername(config.getSecurityUsername());
6871
rc.setPassword(config.getSecurityPassword());
6972
if (config.getSecuritySslContext() != null) {

src/main/java/com/marklogic/mgmt/admin/DefaultAdminConfigFactory.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ public void initialize() {
4242
config.setPort(Integer.parseInt(prop));
4343
});
4444

45+
propertyConsumerMap.put("mlAdminAuthentication", (config, prop) -> {
46+
logger.info("Admin authentication: " + prop);
47+
config.setSecurityContextType(prop);
48+
});
49+
4550
/**
4651
* The Manage API endpoints in the Admin interface still just require the manage-admin role, so the value of
4752
* mlManageUsername should work for these calls.
@@ -68,6 +73,21 @@ public void initialize() {
6873
}
6974
});
7075

76+
propertyConsumerMap.put("mlAdminCertFile", (config, prop) -> {
77+
logger.info("Admin certificate file: " + prop);
78+
config.setCertFile(prop);
79+
});
80+
propertyConsumerMap.put("mlAdminCertPassword", (config, prop) -> {
81+
config.setCertPassword(prop);
82+
});
83+
propertyConsumerMap.put("mlAdminExternalName", (config, prop) -> {
84+
logger.info("Admin external name: " + prop);
85+
config.setExternalName(prop);
86+
});
87+
propertyConsumerMap.put("mlAdminSamlToken", (config, prop) -> {
88+
config.setSamlToken(prop);
89+
});
90+
7191
propertyConsumerMap.put("mlAdminBasePath", (config, prop) -> {
7292
logger.info("Admin base path: " + prop);
7393
config.setBasePath(prop);

src/main/java/com/marklogic/mgmt/api/API.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,9 @@ public void connect(String host, ManageConfig mc) {
8888
if (logger.isInfoEnabled()) {
8989
logger.info("Connecting to host: " + host);
9090
}
91-
SimplePropertySource sps = new SimplePropertySource("mlHost", host, "mlManageUsername", mc.getUsername(),
92-
"mlManagePassword", mc.getPassword(), "mlManageSimpleSsl", mc.isConfigureSimpleSsl() + "",
93-
"mlManageScheme", mc.getScheme(), "mlManagePort", mc.getPort() + "",
94-
"mlSecurityUsername", mc.getSecurityUsername(), "mlSecurityPassword", mc.getSecurityPassword());
95-
this.manageClient = new ManageClient(new DefaultManageConfigFactory(sps).newManageConfig());
91+
ManageConfig newConfig = new ManageConfig(mc);
92+
newConfig.setHost(host);
93+
this.manageClient = new ManageClient(newConfig);
9694
if (logger.isInfoEnabled()) {
9795
logger.info("Connected to host: " + host);
9896
}

src/main/java/com/marklogic/rest/util/RestConfig.java

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,16 @@ public class RestConfig {
1616

1717
private String host;
1818
private int port;
19+
// Defaulting this for backwards-compatibility reasons in 4.5.0
20+
private String securityContextType = "digest";
1921
private String username;
2022
private String password;
2123
private String cloudApiKey;
24+
private String certFile;
25+
private String certPassword;
26+
private String externalName;
27+
private String samlToken;
28+
2229
private String basePath;
2330
private String scheme = "http";
2431

@@ -64,11 +71,14 @@ public DatabaseClientBuilder newDatabaseClientBuilder() {
6471
.withHost(getHost())
6572
.withPort(getPort())
6673
.withBasePath(getBasePath())
67-
// TODO Will support all types before the 4.5.0 release
68-
.withSecurityContextType(StringUtils.hasText(getCloudApiKey()) ? "cloud" : "digest")
74+
.withSecurityContextType(getSecurityContextType())
6975
.withUsername(getUsername())
7076
.withPassword(getPassword())
71-
.withCloudApiKey(getCloudApiKey());
77+
.withCloudApiKey(getCloudApiKey())
78+
.withCertificateFile(getCertFile())
79+
.withCertificatePassword(getCertPassword())
80+
.withKerberosPrincipal(getExternalName())
81+
.withSAMLToken(getSamlToken());
7282

7383
if (getSslContext() != null) {
7484
builder.withSSLContext(getSslContext());
@@ -246,4 +256,44 @@ public String getBasePath() {
246256
public void setBasePath(String basePath) {
247257
this.basePath = basePath;
248258
}
259+
260+
public String getSecurityContextType() {
261+
return securityContextType;
262+
}
263+
264+
public void setSecurityContextType(String securityContextType) {
265+
this.securityContextType = securityContextType;
266+
}
267+
268+
public String getCertFile() {
269+
return certFile;
270+
}
271+
272+
public void setCertFile(String certFile) {
273+
this.certFile = certFile;
274+
}
275+
276+
public String getCertPassword() {
277+
return certPassword;
278+
}
279+
280+
public void setCertPassword(String certPassword) {
281+
this.certPassword = certPassword;
282+
}
283+
284+
public String getExternalName() {
285+
return externalName;
286+
}
287+
288+
public void setExternalName(String externalName) {
289+
this.externalName = externalName;
290+
}
291+
292+
public String getSamlToken() {
293+
return samlToken;
294+
}
295+
296+
public void setSamlToken(String samlToken) {
297+
this.samlToken = samlToken;
298+
}
249299
}

src/test/java/com/marklogic/mgmt/DefaultManageConfigFactoryTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.marklogic.mgmt;
22

3+
import com.marklogic.client.DatabaseClientFactory;
4+
import com.marklogic.mgmt.admin.AdminConfig;
35
import com.marklogic.mgmt.util.SimplePropertySource;
46
import org.junit.jupiter.api.Test;
57

@@ -103,6 +105,7 @@ public void mlManageHost() {
103105
void cloudApiKeyAndBasePath() {
104106
ManageConfig config = configure(
105107
"mlCloudApiKey", "my-key",
108+
"mlManageAuthentication", "cloud",
106109
"mlManageBasePath", "/manage/path",
107110
"mlManagePort", "8002",
108111
"mlManageScheme", "http"
@@ -113,6 +116,53 @@ void cloudApiKeyAndBasePath() {
113116
assertEquals(443, config.getPort(), "When a cloud API key is provided, the mlManagePort and mlManageScheme " +
114117
"options should be overridden since https/443 are guaranteed to be the correct values");
115118
assertEquals("https", config.getScheme());
119+
120+
DatabaseClientFactory.Bean bean = config.newDatabaseClientBuilder().buildBean();
121+
assertTrue(bean.getSecurityContext() instanceof DatabaseClientFactory.MarkLogicCloudAuthContext);
122+
assertEquals("my-key", ((DatabaseClientFactory.MarkLogicCloudAuthContext)bean.getSecurityContext()).getKey());
123+
}
124+
125+
@Test
126+
void certificateAuth() {
127+
ManageConfig config = configure(
128+
"mlManageAuthentication", "certificate",
129+
"mlManageCertFile", "my-file.crt",
130+
"mlManageCertPassword", "passwd"
131+
);
132+
133+
assertEquals("certificate", config.getSecurityContextType());
134+
assertEquals("my-file.crt", config.getCertFile());
135+
assertEquals("passwd", config.getCertPassword());
136+
}
137+
138+
@Test
139+
void kerberosAuth() {
140+
ManageConfig config = configure(
141+
"mlManageAuthentication", "kerberos",
142+
"mlManageExternalName", "my-name"
143+
);
144+
145+
assertEquals("kerberos", config.getSecurityContextType());
146+
assertEquals("my-name", config.getExternalName());
147+
148+
DatabaseClientFactory.Bean bean = config.newDatabaseClientBuilder().buildBean();
149+
assertTrue(bean.getSecurityContext() instanceof DatabaseClientFactory.KerberosAuthContext);
150+
assertEquals("my-name", ((DatabaseClientFactory.KerberosAuthContext)bean.getSecurityContext()).getKrbOptions().get("principal"));
151+
}
152+
153+
@Test
154+
void samlAuth() {
155+
ManageConfig config = configure(
156+
"mlManageAuthentication", "saml",
157+
"mlManageSamlToken", "my-token"
158+
);
159+
160+
assertEquals("saml", config.getSecurityContextType());
161+
assertEquals("my-token", config.getSamlToken());
162+
163+
DatabaseClientFactory.Bean bean = config.newDatabaseClientBuilder().buildBean();
164+
assertTrue(bean.getSecurityContext() instanceof DatabaseClientFactory.SAMLAuthContext);
165+
assertEquals("my-token", ((DatabaseClientFactory.SAMLAuthContext)bean.getSecurityContext()).getToken());
116166
}
117167

118168
private ManageConfig configure(String... properties) {

src/test/java/com/marklogic/mgmt/admin/DefaultAdminConfigFactoryTest.java

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.marklogic.mgmt.admin;
22

3+
import com.marklogic.client.DatabaseClientFactory;
34
import com.marklogic.mgmt.util.SimplePropertySource;
5+
import com.marklogic.rest.util.RestTemplateUtil;
46
import org.junit.jupiter.api.Test;
57

68
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
import static org.junit.jupiter.api.Assertions.assertNotNull;
710
import static org.junit.jupiter.api.Assertions.assertTrue;
811

912
public class DefaultAdminConfigFactoryTest {
@@ -59,17 +62,65 @@ public void sslProperties() {
5962

6063
@Test
6164
void cloudApiKeyAndBasePath() {
62-
AdminConfig config = new DefaultAdminConfigFactory(new SimplePropertySource(
65+
AdminConfig config = configure(
6366
"mlCloudApiKey", "my-key",
67+
"mlAdminAuthentication", "cloud",
6468
"mlAdminBasePath", "/admin/path",
6569
"mlAdminPort", "8001",
6670
"mlAdminScheme", "http"
67-
)).newAdminConfig();
71+
);
6872

6973
assertEquals("my-key", config.getCloudApiKey());
7074
assertEquals("/admin/path", config.getBasePath());
7175
assertEquals(443, config.getPort(), "When a cloud API key is provided, https and 443 should be assumed");
7276
assertEquals("https", config.getScheme());
77+
78+
DatabaseClientFactory.Bean bean = config.newDatabaseClientBuilder().buildBean();
79+
assertTrue(bean.getSecurityContext() instanceof DatabaseClientFactory.MarkLogicCloudAuthContext);
80+
assertEquals("my-key", ((DatabaseClientFactory.MarkLogicCloudAuthContext)bean.getSecurityContext()).getKey());
81+
}
82+
83+
@Test
84+
void certificateAuth() {
85+
AdminConfig config = configure(
86+
"mlAdminAuthentication", "certificate",
87+
"mlAdminCertFile", "my-file.crt",
88+
"mlAdminCertPassword", "passwd"
89+
);
90+
91+
assertEquals("certificate", config.getSecurityContextType());
92+
assertEquals("my-file.crt", config.getCertFile());
93+
assertEquals("passwd", config.getCertPassword());
94+
}
95+
96+
@Test
97+
void kerberosAuth() {
98+
AdminConfig config = configure(
99+
"mlAdminAuthentication", "kerberos",
100+
"mlAdminExternalName", "my-name"
101+
);
102+
103+
assertEquals("kerberos", config.getSecurityContextType());
104+
assertEquals("my-name", config.getExternalName());
105+
106+
DatabaseClientFactory.Bean bean = config.newDatabaseClientBuilder().buildBean();
107+
assertTrue(bean.getSecurityContext() instanceof DatabaseClientFactory.KerberosAuthContext);
108+
assertEquals("my-name", ((DatabaseClientFactory.KerberosAuthContext)bean.getSecurityContext()).getKrbOptions().get("principal"));
109+
}
110+
111+
@Test
112+
void samlAuth() {
113+
AdminConfig config = configure(
114+
"mlAdminAuthentication", "saml",
115+
"mlAdminSamlToken", "my-token"
116+
);
117+
118+
assertEquals("saml", config.getSecurityContextType());
119+
assertEquals("my-token", config.getSamlToken());
120+
121+
DatabaseClientFactory.Bean bean = config.newDatabaseClientBuilder().buildBean();
122+
assertTrue(bean.getSecurityContext() instanceof DatabaseClientFactory.SAMLAuthContext);
123+
assertEquals("my-token", ((DatabaseClientFactory.SAMLAuthContext)bean.getSecurityContext()).getToken());
73124
}
74125

75126
private AdminConfig configure(String... properties) {

0 commit comments

Comments
 (0)