Hello Ben Henny,
Welcome on the Tableau Community forums,
Could you please try to use a browser on the computer on which Tableau Desktop is installed, log in to Tableau Server? If this succeeds, log in from Tableau Desktop use the same URL that was used to log in from the browser.
Let me know how it goes
I'm not working with a Tableau Server at this point. It's an 3rd-party API that I'm trying to build a web data connector for. I can access the API from my browser (using a client certificate). But from the same computer, using the same client certificate, Tableau is not able to retrieve data from it.
Hey Ben, as you suspect, in-between interactive and data gathering phases all context is lost because a new process is started. (This is by design) You can use the username, password, and connectionData fields to pass information to data gathering. I'll go ask a couple more people to look at this thread as we have a similar scenario working with a connector we built.
Product Manager - Cloud
Sorry to hear you're having some issues. If I understand your problem correctly, you are hosting your connector on a URL which requires a client side certificate for mutual SSL. When you initially visit the webpage which is hosting your WDC, you get prompted to select a certificate. When the web page loads back up in the data gathering (headless) phase of the connector, the SSL handshake fails because you aren't prompted to select the certificate.
Unfortunately, we currently don't have any way to prompt to select the certificate in the data gathering phase since we have no UI showing at that point. The workaround we recommend is to host your connector on a URL which doesn't require mutual SSL. Inside the connector, you can prompt the user to select the certificate they'd like to use for mutual SSL via a file picker, and serialize that certificate to the tableau.password field. When the connector loads back up in the data gathering phase, you can include the certificate you serialized in the tableau.password field with the AJAX requests you make to actually retrieve the data for you connector. Tableau actually does this for our Anaplan connector which is written on the WDC platform.
Hope that helps, let me know if you run into issues.
I agree with Samm’s answer. We implemented a certificate based authentication on one of our recent WDC Connectors. I can add some details.
We used an input[type=file] and the FileReader API to upload and read the certificates produced by Anaplan. Those certificates had .cer extension.
When the user upload a certificate file, we catch the change event and got the “file” from event.target.files. Then we parse that value two times to obtain the user and password values.
On the first parsing we read the “subject” property from the file. It returns a string that we use as USER and we set it to Tableau’s API as “username”.
On the second parsing we handle the file in a different format, and we seek for the “pem” property. We use it as “password”, setting it to the Tableau’s API.
In that way, those values will be available on data gathering phase without need of reading the certificate again.
Anaplan’s API uses kind of basic auth. So we read from Tableau’s API the user and password properties, concat them with “:” and enconde base 64. Then we use that value in the Authorization header for every request asking for data.
Our first parsing handles the certificate as an ArrayBuffer. We use the FileReader API to manage it. When we get a buffer value, we are able to extract the “subject” thanks to a crypto library called https://pkijs.org/
Our second parsing handles the certificate as a Binary String (again the FileReader API). The result is encoded by us and concatenated to a required header and footer. The final result is a very long string that is used like the password. That value should looks like:
'-----BEGIN CERTIFICATE-----\r\n' + [here a long alphanumeric string] + '\r\n-----END CERTIFICATE-----\r\n';
So, basically what we do is:
- 1- Store values in tableau.password and tableau.username
- 2- Read the .cer certificate through an input file
- 3- Implement the File Reader API to manage the file as ArrayBuffer and BinaryString
- 4- Look for “subject” and “pem” properties, each of them on the right parsing (2 parsings)
- 5- Use a crypto library to parse the Arraybuffer
Hope it helps!