mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-25 06:28:22 +00:00
Fixed#9427: LDAP-s support connection without MTLS (#10146)
* Fixed#9427: LDAP-s support connection without MTLS * Fixed#9427: LDAP-s support connection without MTLS * Fixed#9427: LDAP-s support connection without MTLS * Fix Json Issues --------- Co-authored-by: Mohit Yadav <105265192+mohityadav766@users.noreply.github.com> Co-authored-by: mohitdeuex <mohit.y@deuexsolutions.com>
This commit is contained in:
parent
b8a6f549e7
commit
5c351781f5
@ -32,10 +32,9 @@ authenticationConfiguration:
|
||||
# Optional
|
||||
"maxPoolSize": ${AUTHENTICATION_LDAP_POOL_SIZE:-3}
|
||||
"sslEnabled": ${AUTHENTICATION_LDAP_SSL_ENABLED:-true}
|
||||
"keyStorePath": ${AUTHENTICATION_LDAP_KEYSTORE_PATH:-"/Users/mohityadav/sslTest/client/keystore.ks"}
|
||||
"keyStorePassword": ${AUTHENTICATION_LDAP_KEYSTORE_PWD:-"secret"}
|
||||
"truststoreFormat": ${AUTHENTICATION_LDAP_SSL_KEY_FORMAT:-"JKS"}
|
||||
"verifyCertificateHostname": ${AUTHENTICATION_LDAP_SSL_VERIFY_CERT_HOST:-"false"}
|
||||
"truststoreConfigType": ${AUTHENTICATION_LDAP_TRUSTSTORE_TYPE:-TrustAll} # {CustomTrustStore, HostName, JVMDefault, TrustAll}
|
||||
"trustStoreConfig":
|
||||
"examineValidityDates": ${AUTHENTICATION_LDAP_EXAMINE_VALIDITY_DATES:-true}
|
||||
```
|
||||
|
||||
For the LDAP auth we need to set:
|
||||
@ -66,11 +65,65 @@ Please see the below image for a sample LDAP Configuration in ApacheDS.
|
||||
Advanced LDAP Specific Configuration (Optional):
|
||||
|
||||
- `maxPoolSize`: Connection Pool Size to use to connect to LDAP Server.
|
||||
- `sslEnabled`: Set to true if the SSL is enable to connecto to LDAP Server.
|
||||
- `keyStorePath`: Path of Keystore in case the sslEnabled is set to true.
|
||||
- `keyStorePassword`: Truststore Password.
|
||||
- `truststoreFormat`: TrustStore Format (Example :- JKS).
|
||||
- `verifyCertificateHostname`: Controls using TrustAllSSLSocketVerifier vs HostNameSSLSocketVerifier. In case the certificate contains cn=hostname of the Ldap Server set it to true.
|
||||
- `sslEnabled`: Set to true if the SSL is enable to connect to LDAP Server.
|
||||
- `truststoreConfigType`: Truststore type. It is required. Can select from {CustomTrustStore, HostName, JVMDefault, TrustAll}
|
||||
- `trustStoreConfig`: Config for the selected truststore type. Please check below note for setting this up.
|
||||
|
||||
<Note>
|
||||
|
||||
Based on the different `truststoreConfigType`, we have following different `trustStoreConfig`.
|
||||
|
||||
1. **TrustAll**: Provides an SSL trust manager which will blindly trust any certificate that is presented to it, although it may optionally reject certificates that are expired or not yet valid. It can be convenient for testing purposes, but it is recommended that production environments use trust managers that perform stronger validation.
|
||||
|
||||
```yaml
|
||||
"truststoreConfigType": ${AUTHENTICATION_LDAP_TRUSTSTORE_TYPE:-TrustAll}
|
||||
"trustStoreConfig":
|
||||
"examineValidityDates": ${AUTHENTICATION_LDAP_EXAMINE_VALIDITY_DATES:-true}
|
||||
```
|
||||
|
||||
- `examineValidityDates`: Indicates whether to reject certificates if the current time is outside the validity window for the certificate.
|
||||
|
||||
2. **JVMDefault**: Provides an implementation of a trust manager that relies on the JVM's default set of trusted issuers.
|
||||
|
||||
```yaml
|
||||
"truststoreConfigType": ${AUTHENTICATION_LDAP_TRUSTSTORE_TYPE:-CustomTrustStore}
|
||||
"trustStoreConfig":
|
||||
"verifyHostname": ${AUTHENTICATION_LDAP_SSL_VERIFY_CERT_HOST:-true}
|
||||
```
|
||||
|
||||
- `verifyHostname`: Controls using TrustAllSSLSocketVerifier vs HostNameSSLSocketVerifier. In case the certificate contains cn=hostname of the Ldap Server set it to true.
|
||||
|
||||
3. **HostName**: Provides an SSL trust manager that will only accept certificates whose hostname matches an expected value.
|
||||
|
||||
```yaml
|
||||
"truststoreConfigType": ${AUTHENTICATION_LDAP_TRUSTSTORE_TYPE:-HostName}
|
||||
"trustStoreConfig":
|
||||
"allowWildCards": ${AUTHENTICATION_LDAP_ALLOW_WILDCARDS:-false}
|
||||
"acceptableHostNames": ${AUTHENTICATION_LDAP_ALLOWED_HOSTNAMES:-[localhost]}
|
||||
```
|
||||
|
||||
- `allowWildCards`: Indicates whether to allow wildcard certificates which contain an asterisk as the first component of a CN subject attribute or dNSName subjectAltName extension.
|
||||
- `acceptableHostNames`: The set of hostnames and/or IP addresses that will be considered acceptable. Only certificates with a CN or subjectAltName value that exactly matches one of these names (ignoring differences in capitalization) will be considered acceptable. It must not be null or empty.
|
||||
|
||||
4. **CustomTrustStore**: Use the custom Truststore by providing the below details in the config.
|
||||
|
||||
```yaml
|
||||
"truststoreConfigType": ${AUTHENTICATION_LDAP_TRUSTSTORE_TYPE:-CustomTrustStore}
|
||||
"trustStoreConfig":
|
||||
"trustStoreFilePath": ${AUTHENTICATION_LDAP_TRUSTSTORE_PATH:-/Users/parthpanchal/trusted.ks}
|
||||
"trustStoreFilePassword": ${AUTHENTICATION_LDAP_KEYSTORE_PASSWORD:-secret}
|
||||
"trustStoreFileFormat": ${AUTHENTICATION_LDAP_SSL_KEY_FORMAT:-JKS}
|
||||
"verifyHostname": ${AUTHENTICATION_LDAP_SSL_VERIFY_CERT_HOST:-true}
|
||||
"examineValidityDates": ${AUTHENTICATION_LDAP_EXAMINE_VALIDITY_DATES:-true}
|
||||
```
|
||||
|
||||
- `trustStoreFilePath`: The path to the trust store file to use. It must not be null.
|
||||
- `trustStoreFilePassword`: The PIN to use to access the contents of the trust store. It may be null if no PIN is required.
|
||||
- `trustStoreFileFormat`: The format to use for the trust store. (Example :- JKS, PKCS12).
|
||||
- `verifyHostname`: Controls using TrustAllSSLSocketVerifier vs HostNameSSLSocketVerifier. In case the certificate contains cn=hostname of the Ldap Server set it to true.
|
||||
- `examineValidityDates`: Indicates whether to reject certificates if the current time is outside the validity window for the certificate.
|
||||
|
||||
</Note>
|
||||
|
||||
### Authorizer Configuration
|
||||
|
||||
|
||||
@ -22,13 +22,10 @@ import com.unboundid.ldap.sdk.SearchRequest;
|
||||
import com.unboundid.ldap.sdk.SearchResult;
|
||||
import com.unboundid.ldap.sdk.SearchResultEntry;
|
||||
import com.unboundid.ldap.sdk.SearchScope;
|
||||
import com.unboundid.util.ssl.AggregateTrustManager;
|
||||
import com.unboundid.util.ssl.HostNameSSLSocketVerifier;
|
||||
import com.unboundid.util.ssl.JVMDefaultTrustManager;
|
||||
import com.unboundid.util.ssl.SSLSocketVerifier;
|
||||
import com.unboundid.util.ssl.SSLUtil;
|
||||
import com.unboundid.util.ssl.TrustAllSSLSocketVerifier;
|
||||
import com.unboundid.util.ssl.TrustStoreTrustManager;
|
||||
import freemarker.template.TemplateException;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
@ -51,6 +48,7 @@ import org.openmetadata.service.jdbi3.TokenRepository;
|
||||
import org.openmetadata.service.jdbi3.UserRepository;
|
||||
import org.openmetadata.service.security.AuthenticationException;
|
||||
import org.openmetadata.service.util.EmailUtil;
|
||||
import org.openmetadata.service.util.LdapUtil;
|
||||
import org.openmetadata.service.util.TokenUtil;
|
||||
|
||||
@Slf4j
|
||||
@ -77,26 +75,16 @@ public class LdapAuthenticator implements AuthenticatorHandler {
|
||||
this.loginConfiguration = config.getLoginSettings();
|
||||
}
|
||||
|
||||
private SSLSocketVerifier hostNameVerifier(boolean verifyHostName) {
|
||||
return verifyHostName ? new HostNameSSLSocketVerifier(true) : TrustAllSSLSocketVerifier.getInstance();
|
||||
}
|
||||
|
||||
private LDAPConnectionPool getLdapConnectionPool(LdapConfiguration ldapConfiguration) {
|
||||
try {
|
||||
if (ldapConfiguration.getSslEnabled()) {
|
||||
AggregateTrustManager trustManager =
|
||||
new AggregateTrustManager(
|
||||
false,
|
||||
JVMDefaultTrustManager.getInstance(),
|
||||
new TrustStoreTrustManager(
|
||||
ldapConfiguration.getKeyStorePath(),
|
||||
ldapConfiguration.getKeyStorePassword().toCharArray(),
|
||||
ldapConfiguration.getTruststoreFormat(),
|
||||
true));
|
||||
SSLUtil sslUtil = new SSLUtil(trustManager);
|
||||
|
||||
LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions();
|
||||
SSLSocketVerifier sslSocketVerifier =
|
||||
ldapConfiguration.getVerifyCertificateHostname()
|
||||
? new HostNameSSLSocketVerifier(true)
|
||||
: TrustAllSSLSocketVerifier.getInstance();
|
||||
connectionOptions.setSSLSocketVerifier(sslSocketVerifier);
|
||||
LdapUtil ldapUtil = new LdapUtil();
|
||||
SSLUtil sslUtil = new SSLUtil(ldapUtil.getLdapSSLConnection(ldapConfiguration, connectionOptions));
|
||||
|
||||
try (LDAPConnection connection =
|
||||
new LDAPConnection(
|
||||
@ -124,9 +112,8 @@ public class LdapAuthenticator implements AuthenticatorHandler {
|
||||
}
|
||||
}
|
||||
} catch (LDAPException e) {
|
||||
LOG.warn("[LDAP] Issue in creating a LookUp Connection");
|
||||
throw new IllegalStateException("[LDAP] Issue in creating a LookUp Connection SSL", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
package org.openmetadata.service.util;
|
||||
|
||||
import com.unboundid.ldap.sdk.LDAPConnectionOptions;
|
||||
import com.unboundid.util.ssl.HostNameSSLSocketVerifier;
|
||||
import com.unboundid.util.ssl.HostNameTrustManager;
|
||||
import com.unboundid.util.ssl.JVMDefaultTrustManager;
|
||||
import com.unboundid.util.ssl.SSLSocketVerifier;
|
||||
import com.unboundid.util.ssl.TrustAllSSLSocketVerifier;
|
||||
import com.unboundid.util.ssl.TrustAllTrustManager;
|
||||
import com.unboundid.util.ssl.TrustStoreTrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.openmetadata.schema.auth.LdapConfiguration;
|
||||
import org.openmetadata.schema.auth.ldapTrustStoreConfig.CustomTrustManagerConfig;
|
||||
import org.openmetadata.schema.auth.ldapTrustStoreConfig.HostNameConfig;
|
||||
import org.openmetadata.schema.auth.ldapTrustStoreConfig.JVMDefaultConfig;
|
||||
import org.openmetadata.schema.auth.ldapTrustStoreConfig.TrustAllConfig;
|
||||
|
||||
public class LdapUtil {
|
||||
|
||||
public X509TrustManager getLdapSSLConnection(
|
||||
LdapConfiguration ldapConfiguration, LDAPConnectionOptions connectionOptions) {
|
||||
X509TrustManager x509TrustManager;
|
||||
SSLSocketVerifier sslSocketVerifier;
|
||||
connectionOptions = new LDAPConnectionOptions();
|
||||
LdapConfiguration.TruststoreConfigType configType = ldapConfiguration.getTruststoreConfigType();
|
||||
switch (configType) {
|
||||
case CUSTOM_TRUST_STORE:
|
||||
CustomTrustManagerConfig customTrustManagerConfig =
|
||||
JsonUtils.convertValue(ldapConfiguration.getTrustStoreConfig(), CustomTrustManagerConfig.class);
|
||||
x509TrustManager =
|
||||
new TrustStoreTrustManager(
|
||||
customTrustManagerConfig.getTrustStoreFilePath(),
|
||||
customTrustManagerConfig.getTrustStoreFilePassword().toCharArray(),
|
||||
customTrustManagerConfig.getTrustStoreFileFormat(),
|
||||
customTrustManagerConfig.getExamineValidityDates());
|
||||
sslSocketVerifier = hostNameVerifier(customTrustManagerConfig.getVerifyHostname());
|
||||
connectionOptions.setSSLSocketVerifier(sslSocketVerifier);
|
||||
break;
|
||||
case HOST_NAME:
|
||||
HostNameConfig hostNameConfig =
|
||||
JsonUtils.convertValue(ldapConfiguration.getTrustStoreConfig(), HostNameConfig.class);
|
||||
x509TrustManager =
|
||||
new HostNameTrustManager(hostNameConfig.getAllowWildCards(), hostNameConfig.getAcceptableHostNames());
|
||||
break;
|
||||
case JVM_DEFAULT:
|
||||
JVMDefaultConfig jvmDefaultConfig =
|
||||
JsonUtils.convertValue(ldapConfiguration.getTrustStoreConfig(), JVMDefaultConfig.class);
|
||||
x509TrustManager = JVMDefaultTrustManager.getInstance();
|
||||
sslSocketVerifier = hostNameVerifier(jvmDefaultConfig.getVerifyHostname());
|
||||
connectionOptions.setSSLSocketVerifier(sslSocketVerifier);
|
||||
break;
|
||||
case TRUST_ALL:
|
||||
TrustAllConfig trustAllConfig =
|
||||
JsonUtils.convertValue(ldapConfiguration.getTrustStoreConfig(), TrustAllConfig.class);
|
||||
x509TrustManager = new TrustAllTrustManager(trustAllConfig.getExamineValidityDates());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid Truststore type.");
|
||||
}
|
||||
return x509TrustManager;
|
||||
}
|
||||
|
||||
private SSLSocketVerifier hostNameVerifier(boolean verifyHostName) {
|
||||
return verifyHostName ? new HostNameSSLSocketVerifier(true) : TrustAllSSLSocketVerifier.getInstance();
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,6 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["username", "password"],
|
||||
"required": ["email", "password"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -13,6 +13,6 @@
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"username"
|
||||
"email"
|
||||
]
|
||||
}
|
||||
@ -47,7 +47,7 @@
|
||||
},
|
||||
"ldapConfiguration": {
|
||||
"description": "LDAP Configuration in case the Provider is LDAP",
|
||||
"$ref": "../auth/ldapConfiguration.json"
|
||||
"$ref": "./ldapConfiguration.json"
|
||||
}
|
||||
},
|
||||
"required": ["provider", "providerName", "publicKeyUrls", "authority", "callbackUrl", "clientId", "jwtPrincipalClaims"],
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/api/auth/ldapConfiguration.json",
|
||||
"$id": "https://open-metadata.org/schema/configuration/ldapConfiguration.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "LdapConfiguration",
|
||||
"description": "LDAP Configuration",
|
||||
@ -37,32 +37,40 @@
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"keyStorePath": {
|
||||
"description": "Path of the Keystore for SSL",
|
||||
"type": "string"
|
||||
},
|
||||
"keyStorePassword": {
|
||||
"description": "Password of the Keystore",
|
||||
"type": "string"
|
||||
},
|
||||
"userBaseDN": {
|
||||
"description": "Password for LDAP Admin",
|
||||
"description": "User base distinguished name",
|
||||
"type": "string"
|
||||
},
|
||||
"mailAttributeName": {
|
||||
"description": "Password for LDAP Admin",
|
||||
"description": "Email attribute name",
|
||||
"type": "string"
|
||||
},
|
||||
"truststoreFormat": {
|
||||
"description": "Password for LDAP Admin",
|
||||
"description": "Truststore format e.g. PKCS12, JKS.",
|
||||
"type": "string"
|
||||
},
|
||||
"verifyCertificateHostname": {
|
||||
"description": "If true use HostNameSSLVerifier(only then trust store cn as hostname) else TrustAll ",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
"truststoreConfigType": {
|
||||
"description": "Truststore Type e.g. TrustAll, HostName, JVMDefault, CustomTrustStore.",
|
||||
"type": "string",
|
||||
"enum": ["TrustAll", "JVMDefault", "HostName", "CustomTrustStore"]
|
||||
},
|
||||
"trustStoreConfig": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "./ldapTrustStoreConfig/customTrustManagerConfig.json"
|
||||
},
|
||||
{
|
||||
"$ref": "./ldapTrustStoreConfig/hostNameConfig.json"
|
||||
},
|
||||
{
|
||||
"$ref": "./ldapTrustStoreConfig/jvmDefaultConfig.json"
|
||||
},
|
||||
{
|
||||
"$ref": "./ldapTrustStoreConfig/trustAllConfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["host", "port", "dnAdminPrincipal","dnAdminPassword", "userBaseDN", "mailAttributeName"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/configuration/ldapTrustStoreConfig/customTrustManagerConfig.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "CustomTrustManagerConfig",
|
||||
"description": "CustomTrust Configuration",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.schema.auth.ldapTrustStoreConfig.CustomTrustManagerConfig",
|
||||
"properties": {
|
||||
"verifyHostname": {
|
||||
"description": "list of host names to verify",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"examineValidityDates": {
|
||||
"description": "Examine validity dates of certificate",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"trustStoreFilePath": {
|
||||
"description": "Truststore file path",
|
||||
"type": "string"
|
||||
},
|
||||
"trustStoreFilePassword": {
|
||||
"description": "Truststore file password",
|
||||
"type": "string"
|
||||
},
|
||||
"trustStoreFileFormat": {
|
||||
"description": "Truststore file format",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/configuration/ldapTrustStoreConfig/hostNameConfig.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "HostNameConfig",
|
||||
"description": "HostName Configuration",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.schema.auth.ldapTrustStoreConfig.HostNameConfig",
|
||||
"properties": {
|
||||
"allowWildCards": {
|
||||
"description": "Allow wildcards",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"acceptableHostNames": {
|
||||
"description": "list of acceptable host names",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/configuration/ldapTrustStoreConfig/jvmDefaultConfig.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "JVMDefaultConfig",
|
||||
"description": "JVMDefault Configuration",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.schema.auth.ldapTrustStoreConfig.JVMDefaultConfig",
|
||||
"properties": {
|
||||
"verifyHostname": {
|
||||
"description": "list of host names to verify",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/configuration/ldapTrustStoreConfig/trustAllConfig.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "TrustAllConfig",
|
||||
"description": "TrustAll Configuration",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.schema.auth.ldapTrustStoreConfig.TrustAllConfig",
|
||||
"properties": {
|
||||
"examineValidityDates": {
|
||||
"description": "Examine validity dates of certificate",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -69,5 +69,5 @@
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["to", "subject", "contentType"]
|
||||
"required": ["subject", "contentType"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user