Tableau Server is getting more and more enterprise ready, it includes crucial enterprise functionality like support for SAML IdP and Server REST API. This makes possible to implement non-directly supported features like LDAP authentication and authorization – even for non active directory based LDAP servers such OpenLDAP. In the following post I will summarize what do you need to setup the standard and supported connection between your Tableau and LDAP infrastructure.
Authentication
Tableau Server support local (internal), SAML, Kerberos and Trusted authentication – but no LDAP out of the box. However, most of the SAML IdPs supports LDAP so by adding an SAML server to your infrastructure you can delegate Tableau Desktop and Tableau Server authentication to your LDAP via SAML IdP. SAML even allows you to design your own login screen as Craig described in his SAML post.
You can download some of the widely used, funny named free/open source SAML Identity providers like:
- shibboleth – https://shibboleth.net/products/identity-provider.html
- glue – http://www.gluu.org/
You can simply follow the vendor documentations on how to setup the Identity providers with LDAP. When you ready just have a look in Tableau’s SAML Configuration guide and proceed with its steps.
That’s it, now you can logon with your LDAP based username-password information to Tableau Server!
Authorization
The next step is to import and synchronize users between LDAP and Tableau Server. I wrote a small utility for this purpose which could replicate users and user group memberships between Tableau Server 9.0+ and any LDAP server. It
- Synchronizes multiple ldap groups with multiple tableau groups on multiple sites using official Tableau Server REST API
- Adds all users to tableau site who are defined in LDAP but not existing in Tableau Server
- Synchronizes each ldap group with the corresponding tableau group (adds, deletes users according to actual LDAPmemberships)
- Sets domain to users to be able to use Active Directory authentication after synchronization (optional)
- can be deployed as single standalone JAR file without any interpreter dependency (with lein uberjar ).
This is very similar what Tableau does with Active Directory groups.
To install the app go to tabsync’s github page: https://github.com/starschema/tabsync and follow the install instruction. You will need java 1.8 and leiningen installed on your local PC.
To begin create a directory called config in the root of your newly created jar executable, and make sure to place a file called groups.yml under the same directory. Make sure to follow the formatting pattern:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
ldap: host: ldap.domain.com:389 username: "cn=administrator,ou=Sample,dc=AD,dc=company,dc=com" password: administrator ad: domain: local email: from: tableau.sync.script@company.com to: john.doe@company.com subject: Tableau Sync Script Report tableau: url: "http://127.0.0.1:8000/" version: 9 username: tableauadmin password: password sites: - name: Site1 group_mapping: - ldap: grp12345 tableau: LDAP Group 1 - name: Site2 group_mapping: - ldap: grp54321 tableau: LDAP Group 2 |
You should also modify two functions in order to use your own LDAP schema for getting users from a group and their user info.
Function 1: Get detailed user info. Use employeNumber
ldap attribute as username, displayName
as full name, email
as email.
1 2 3 4 5 6 7 |
(defn get-user-info "Gets the user's SSO & email address" [sso] (let [user-info (ldap/get ldap-server (str "CN=" sso ",ou=All Businesses,dc=CDIAD,dc=corporate,dc=com"))] (log/debug user-info) {:sso (get user-info :employeeNumber) :name (beautify-display-name (get user-info :displayName)) :mail (get user-info :mail)})) |
Function 2: Get users from group. First search for group in OU=Groups
as CN=group-id
, then take the first nine letters from the returned CNs. In case of the return CN starts with character ‘g’ it will recursively go into it and add to the user list (nested LDAP group handling).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
(defn get-users-from-group "Gets the list of users associated to each LDAP group" [group-id] (log/info "Getting users for ldap group " group-id) (let [group-info (ldap/get ldap-server (str "CN=" group-id ",OU=Groups,DC=CDIAD,dc=corporate,dc=com"))] (->> (get group-info :member) (list) (flatten) (map #(second (re-find #"CN=([a-zA-Z0-9]+{9})" %))) (map (fn [cn] (if (= (get cn 0) \g) (get-users-from-group cn) cn ))) (flatten) (distinct)))) |
Feel free to change these parts according to your LDAP scheme.
Finally, you can run the synchronization tool as:
1 |
$ java -jar tabsync-0.1.0-standalone.jar [args] |
If you have any questions or suggestion just drop me a line as usual.
- Tableau Extensions Addons Introduction: Synchronized Scrollbars - December 2, 2019
- Tableau External Services API: Adding Haskell Expressions as Calculations - November 20, 2019
- Scaling out Tableau Extracts – Building a distributed, multi-node MPP Hyper Cluster - August 11, 2019