Session-level Single-Sign On

Tableau Server doesn’t currently (as of 2018.2) have a dedicated “service” for authentication when doing Single Sign-On. Instead, a Tableau Server session is established the first time you load a Viz using a given SSO method. Whether using Trusted Authentication, Windows Authentication, or SAML, when the first viz loads, that is when the authentication actually happens, and after that point, there is a Tableau Server session cookie, so that the authentication doesn’t have to happen continuously.

Traditionally, particularly for Trusted Authentication, instructions have been given to request and send a new ticket for each load of any Viz. But this introduces extra, unnecessary authentication requests, and can even lead to a “race condition” when you are loading multiple Vizes in the same page, where sessions are being created and overriding each other as separate tickets are processing at the same time. This same issue can affect ANY of the SSO methods when loading multiple vizes.

The Hidden / Empty Viz Solution

As mentioned above, once the first Viz has been authenticated, there is a Tableau Server Sesssion cookie that will be used for all subsequent requests. So to create a “login” service, we simply need to login as quickly as possible to a Viz. This is very similar to what you need to do for Trusted Authentication SSO into the full Tableau Server UI.

The simplest Viz possible is all we need (literally, a single filter on a page using a totally blank Data Source can be used). Every user is the Tableau Server should have access to this Viz. As soon as the user is authenticated into the main application, you should load the simple viz — if using Trusted Authentication, this request should include the trusted ticket. You can hide the Viz div under something or out of sight (the div shouldn’t actually have visibility:hidden though because some browsers don’t like that prior to the Viz being initialized), so that the user doesn’t see this load process. Or do it quickly in a page that then redirects to the next page. It’s up to you.

For even more performance, you can request the PNG version of the Tableau viz, which will return an image instead of loading the full JS viz object. All that is required is adding “.png” to the ending of the Viz location you would be loading, for it to be an image request. Given that ability, you can actually redeem the trusted ticket completely in JavaScript prior to initializing the Viz using the Tableau JS API. You can do this anywhere in the site once you know who the user is; redeeming the Trusted Ticket will establish the Tableau Server session and any subsequent viz renderings will use that session.:

<pre>// One way to redeem a trusted ticket would be a .png request
function redeemTrustedPng(tableauServerBaseUrl, siteContentUrl, workbook, view, trustedTicket){

    if(siteContentUrl === null){
        redemptionUrl = tableauServerBaseUrl + "/trusted/" + trustedTicket + "/views/" + workbook + "/" + view + ".png";
    }
    else{
        redemptionUrl = tableauServerBaseUrl + "/trusted/" + trustedTicket + "/t/" + siteContentUrl + "/views/" + workbook + "/" + view + ".png";
    }
    // Now load the image, but not actual place in the visible part of the DOM
    var redemptionImg = new Image();
    redemptionImg.onload =  function () {
        console.log("Trusted ticket redeemed!")
        trustedImageLoadResponse(true);

    }
    redemptionImg.onerror = function () {
        console.log("Trusted ticket image retrieval failed");
        trustedImageLoadResponse(false);
    }

    // Actually load the image here
    redemptionImg.src = redemptionUrl;
}

function trustedImageLoadResponse(response){
    // This is a stub for the page itself to do something with

}</pre>

Session Timeout with Trusted Tickets

The one advantage of continually sending Trusted Tickets is that the Tableau Server session is continually extending as each ticket is sent. If you only do one Trusted Ticket to establish a session, how do you keep from timing out and sending the user to the Tableau Server sign-in box? The answer is to set your own timer cookie, and whenever it times out, reestablish the session using the Empty Viz. You shouldn’t need to do this with SAML or AD, because they will automatically call out and reestablish their sessions, but you could.

Sign-Out

Tableau Server sessions will end naturally based on the value you have set for them using tabadmin / TSM. Actually forcing a Tableau Session to sign-out is a little tricky — recent versions of Tableau Server understand a SAML IdP Signout, or you could try to use the REST API to signout, but in the latest version of Tableau Server, the REST API technique requires reverting to a simpler, less secure type of session cookie.

2 comments

Leave a comment