LDAP Authentication
You are looking at an older version of the documentation. The latest version is found here.
With the LDAP authentication mechanism, users (and passwords) and roles (or groups) are loaded from an Active Directory or LDAP domain.
Encrypting Credentials in the Configuration
To encode credentials defined in dvserver-standalone.xml, do the following:
- Encrypt the password using the
UTILS.encrypt
function:
SELECT UTILS.encrypt('password');;
- Set encoded values for
java.naming.security.credentials
andbindCredential
:
<module-option name="java.naming.security.credentials" value="ZjyMp28QJE0D47Rld0LOFw=="/>
<module-option name="bindCredential" value="ZjyMp28QJE0D47Rld0LOFw=="/>
- Set
dv.encrypted.credentials
toTRUE
:
<module-option name="dv.encrypted.credentials" value="true"/>
Configuration
To use authentication based on LDAP, you need to configure the <authentication> section in the current dv-security security-domain defined in dvserver-standalone.xml.
Here is an example configuration:
<security-domain name="dv-security" cache-type="default">
<authentication>
<login-module code="com.datavirtuality.dv.core.teiid.users.ldap.ext.DVLdapExtLoginModule" module="com.datavirtuality.dv" flag="required">
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<module-option name="java.naming.provider.url" value="ldap://192.168.0.68/"/>
<module-option name="java.naming.security.authentication" value="simple"/>
<module-option name="java.naming.security.principal" value="CN=Administrator,CN=Users,DC=mydomain,DC=local"/>
<module-option name="java.naming.security.credentials" value="Password123"/>
<module-option name="bindDN" value="CN=Administrator,CN=Users,DC=mydomain,DC=local"/>
<module-option name="bindCredential" value="Password123"/>
<module-option name="baseCtxDN" value="DC=mydomain,DC=local"/>
<module-option name="baseFilter" value="(CN={0})"/>
<module-option name="rolesCtxDN" value="OU=dvroles,DC=mydomain,DC=local"/>
<module-option name="roleFilter" value="(member={1})"/>
<module-option name="roleAttributeIsDN" value="false"/>
<module-option name="roleAttributeID" value="cn"/>
<module-option name="roleRecursion" value="5"/>
<module-option name="searchFilterUsers" value="(memberof=cn=DataVirtuality,OU=Users,DC=mydomain,DC=local)"/>
<module-option name="searchFilterGroups" value="CN=DataVirtuality"/>
<module-option name="allowEmptyPasswords" value="false"/>
<module-option name="defaultAdminGroup" value="dv-admins"/>
</login-module>
</authentication>
</security-domain>
This code replaces the following one in dvserver-standalone.xml:
<security-domain name="dv-security" cache-type="default">
<authentication>
<login-module code="com.datavirtuality.dv.core.teiid.users.DVLoginModule" flag="required" module="com.datavirtuality.dv"/>
</authentication>
</security-domain>
The parameters should be configured as follows:
To view the full table, click the expand button in its top right corner
Parameter | Description |
---|---|
java.naming.provider.url | Hostname or IP address of directory server. Can use |
java.naming.security.principal | User account that has permissions to read users and groups from the directory |
java.naming.security.credentials | Credentials of the user account above |
bindDN | Same as java.naming.security.principal . For technical reasons, the same credentials need to be supplied twice |
bindCredential | Same as java.naming.security.credentials |
baseCtxDN | The container where to start searching for roles |
baseFilter | When a user logs in, this filter locates the user inside the directory based on the provided username passed as {0} . Different types of filters are possible, such as using the CN ((cn={0}) ), userPrincipalName ((userPrincipalName={0}@mydomain.local) ), or sAMAccountName ((sAMAccountName={0}) ) |
searchFilterGroups | Optional filter to restrict the groups that the login module will retrieve. By default, all groups under rolesCtxDN are loaded as (&(&(objectClass=group))) . Specify a more restrictive filter if you want only a subset of groups to be loaded |
searchFilterUsers | Optional filter to restrict the users that the login module will retrieve. By default, all users under baseCtxDN are loaded as (&(&(objectClass=user))) . Specify a more restrictive filter if you want only a subset of users to be loaded |
rolesCtxDN | The container where to start searching for roles |
roleFilter | Filter to obtain groups a user belongs to. The users' userDN can be accessed as {1} |
roleAttributeIsDN | Set to FALSE if the user's role attribute doesn't contain the fully distinguished name of the role object |
roleAttributeID | If roleAttributeIsDN is FALSE , specifies the name of the role attribute which corresponds to the name of the role |
roleRecursion | The depth to search for a role in the given role context. Disabled if set to 0 |
allowEmptyPasswords | Set to FALSE if logins without a password should be rejected |
defaultAdminGroup | Name of the Active Directory role to be granted administrative rights on the Data Virtuality Server |
Сonnecting to the Active Directory server over the TLS protocol requires the following parameter:
<module-option name="java.naming.security.protocol" value="ssl"/>
Please note that the number of domain users visible in the Data Virtuality Studio is limited by the ADWS MaxGroupOrMemberEntries
setting and the Active Directory LDAP default MaxPageSize
setting. Please refer to the ADWS and LDAP documentation for more information.
Users and Roles (or Groups)
Users and Roles lists are loaded from Active Directory. Lists are loaded during the first call to the relevant tables after the server start or restart (SYSADMIN.Users
and SYSADMIN.Roles
) and cached on the server. New users are able to log in to Data Virtuality without refreshing the cache. However, to query new users and roles, the cache must be refreshed using the SYSADMIN.refreshLdapUserCache
procedure.
CALL "SYSADMIN.refreshLdapUserCache"();;
When the Data Virtuality Server is configured to read users, passwords, and roles from an LDAP domain, some features related to these objects can no longer be used in the Data Virtuality Server. In particular, handling users and roles from the Data Virtuality Server is impossible: they should be managed directly in LDAP.
For this reason, the following stored procedures are not available anymore:
SYSADMIN.addRole()
SYSADMIN.renameRole()
SYSADMIN.deleteRole()
SYSADMIN.importUser()
SYSADMIN.addUser()
SYSADMIN.renameUser()
SYSADMIN.deleteUser()
SYSADMIN.changeUserPwd()
SYSADMIN.getEncryptedUserPwd()
SYSADMIN.addUserRole()
SYSADMIN.deleteUserRole()
If they are called, this error message is shown:
UnsupportedLdapUsersHandlerOperationException. This operation is not supported when LDAP is used for the authentication.
Permissions
Permissions are handled and stored locally in dvconfig, and they can be set using the SYSADMIN.setPermissions()
system procedure as with the default dvconfig-based authentication mechanism.
Special Permission to Create Temporary Tables
With the default Data Virtuality Server mechanism, the special permission to create temporary tables is normally assigned to a role, and it is set when a new role is created via SYSADMIN.addRole()
.
Since the Data Virtuality Server with LDAP authentication mechanism cannot handle roles, a procedure to grant or revoke that permission is also provided.
SYSADMIN.setAllowCreateTempTables(IN role_name string NOT NULL, IN allow boolean NOT NULL)
This procedure can be used with both authentication mechanisms and will grant/deny the appropriate permission to the role.
The main difference (but this is only a technical detail) is that if a dvconfig-based authentication is used, the special permission is set to the role and stored in the dv_roles
table, as usual; if LDAP is configured for authenticating users, the special permission is stored in a new and appropriate table called dv_ldap_role_props
.
Adding a Role with Minimal Permissions
Perform the following steps to create a role with minimum permissions for connecting to the Data Virtuality Server. You might not want to have all users granted admin rights.
1. Create a new group in your directory. Ensure that it is within the search scope of the configuration of the login module.
2. If necessary, create a user that shall not be an administrator.
3. Assign the user to the group. Double-check (see the screenshot):
4. Connect to the Data Virtuality Server as an administrator and go to User Management in the Studio. Check that the Server has recognized the users, roles and assignments.
If not, look at the login module configuration and the directory structure. The screenshot depicts the case where everything was correctly read from the directory:
5. Assign the role a minimal set of permissions. You can use the following script (remember to replace custom-connect-role
with your role name):
BEGIN
DECLARE string roleName='custom-connect-role';
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN', "permissions" => 'R') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getInstalledLicense', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getServerVersion', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getServerBuildInfo', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getCurrentDWH', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.refreshDataSource', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.refreshAllDataSources', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getDefaultOptionValue', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getUserProperty', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getDataCatalogAttribute', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.reservedwords', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getCatalogs', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getViewAndProcCreationOrder', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.refreshSchema', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.getDataLineage', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.setRemark', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.refreshAllSchemas', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSADMIN.md5', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'UTILS.getJobProperties', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'UTILS.getConnectorProperties', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'UTILS.pipes_helper__status', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'INFORMATION_SCHEMA', "permissions" => 'RE') ;
CALL SYSADMIN.setPermissions("role_name" => roleName, "resourceName" => 'SYSLOG', "permissions" => 'R') ;
END ;;
All users that belong to this group in your directory will now be able to connect.