Pages

12 September, 2013

How Trusted Authentication Works in Tableau Server

The diagram below describes how trusted authentication works between the client's web browser, your web server(s) and Tableau Server.


User visits the webpage: When a user visits the webpage with the embedded Tableau Server view, it sends a GET request to your web server for the HTML for that page.

Web server passes the URL to the browser: The web server constructs the URL for the view using either the view’s URL or its object tag (if the view’s embedded), and inserts it into the HTML for the page. The ticket is included (e.g., http://tabserver/trusted/<ticket>/views/requestedviewname). The web server passes all the HTML for the page back to the client’s web browser.

Web server POSTS to Tableau Server: The web server sends a POST request to Tableau Server. That POST request must have a username parameter. Theusername value must be the username for a licensed Tableau Server user. If the server is running multiple sites and the view is on a site other than the Default site, the POST request must also include a target_siteparameter.

Browser requests view from Tableau Server: The client web browser sends a request to Tableau Server using a GET request that includes the URL with the ticket.

Tableau Server creates a ticket: Tableau Server checks the IP address of the web server (192.168.1.XXX in the above diagram) that sent the POST request. If it is set up as a trusted host then Tableau Server creates a ticket in the form of a unique nine-digit string. Tableau Server responds to the POST request with that ticket. If there is an error and the ticket cannot be created Tableau Server responds with a value of -1.

Tableau Server redeems the ticket: Tableau Server sees that the web browser requested a URL with a ticket in it and redeems the ticket. Tickets must be redeemed within three minutes after they are issued. Once the ticket is redeemed, Tableau Server logs the user in, removes the ticket from the URL, and sends back the final URL for the embedded view.

Trusted Authentication for Tableau server

 Trusted Authentication TABLEAU:

Step 1: Create a TableauAuthServlet Class
 
package com.tableau;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Properties;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TableauAuthServlet extends HttpServlet
{
       private static final long serialVersionUID = 1L;

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    try
    {
        // Read Property file and config data
        Properties config = getConfigProps();
        final String wgserver = config.getProperty("TableauServerURL");
        final String params = config.getProperty("displayParam");
        System.out.println("Tableau Server URL " + wgserver);
        System.out.println("Tableau display Param " + params);
        System.out.println("LDAP groups" + request.getHeader("groupList"));

        // Read Parameters from url
        String site = request.getParameter("s");
        String workbook = request.getParameter("w");
        String view = request.getParameter("v");
        String groupName = request.getParameter("g");
        System.out.println("site " + site);
        System.out.println("workbook " + workbook);
        System.out.println("view " + view);

        String tabGroupUserID = getTabGroup(groupName, request.getHeader("groupList"));

              String user = request.getHeader("uid");
        System.out.println("user " + user);

        // Get Trusted ticket from Tableau
        final String dst1 = "t/" + site + "/views/" + workbook + "/" + view;
        System.out.println("dst1 IS : " + dst1);
        // String ticket = getTrustedTicket(wgserver, user,
        // request.getRemoteAddr(),site);
        String ticket = getTrustedTicket(wgserver, tabGroupUserID, request.getRemoteAddr(), site);
        System.out.println("remoteAdd " + request.getRemoteAddr());
        System.out.println("ticket " + ticket);
        System.out.println("tabGroupUserID is: " + tabGroupUserID);

        if (!ticket.equals("-1")) //&& (tabGroupUserID.equals("FinanceReport") || tabGroupUserID.equals("SepgReport")) )
        {
        response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
        // response.setHeader("Location", "http://" + wgserver +
        // "/trusted/" + ticket + "/" + dst + "?" + params);

        request.setAttribute("tabserverip", wgserver);
        request.setAttribute("url", "trusted/" + ticket + "/" + dst1);
        request.setAttribute("userid", request.getHeader("uid"));
        request.setAttribute("groupid", getTabGroup(groupName, request.getHeader("groupList")));

        // response.sendRedirect("http://" + wgserver + "/trusted/" +
        // ticket + "/" + dst1 + "?" + params);
    
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/report.jsp");
        dispatcher.forward(request, response);

        }
        else
        {
        // handle error
        // throw new ServletException("Invalid ticket " + ticket);
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/norights.jsp");
        dispatcher.forward(request, response);
        }

    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    }

    // the client_ip parameter isn't necessary to send in the POST unless you
    // have
    // wgserver.extended_trusted_ip_checking enabled (it's disabled by default)

    private String getTrustedTicket(String wgserver, String user, String remoteAddr, String sitename) throws ServletException
    {
    OutputStreamWriter out = null;
    BufferedReader in = null;
    try
    {
        // Encode the parameters
        StringBuffer data = new StringBuffer();
        data.append(URLEncoder.encode("username", "UTF-8"));
        data.append("=");
        data.append(URLEncoder.encode(user, "UTF-8"));
        data.append("&");
        data.append(URLEncoder.encode("client_ip", "UTF-8"));
        data.append("=");
        data.append(URLEncoder.encode(remoteAddr, "UTF-8"));
        data.append("&");
        data.append(URLEncoder.encode("target_site", "UTF-8"));
        data.append("=");
        data.append(URLEncoder.encode(sitename, "UTF-8"));

        // Send the request
        URL url = new URL("http://" + wgserver + "/trusted");
        URLConnection conn = url.openConnection();
        conn.setDoOutput(true);
        out = new OutputStreamWriter(conn.getOutputStream());
        out.write(data.toString());
        out.flush();

        // Read the response
        StringBuffer rsp = new StringBuffer();
        in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = in.readLine()) != null)
        {
        rsp.append(line);
        }

        return rsp.toString();

    }
    catch (Exception e)
    {
        throw new ServletException(e);
    }
    finally
    {
        try
        {
        if (in != null)
            in.close();
        if (out != null)
            out.close();
        }
        catch (IOException e)
        {
        }
    }
    }

    public Properties getConfigProps()
    {

    // Reading properties file to set Default values
    Properties config = new Properties();
    try
    {
        config.load(new FileInputStream(getServletContext().getRealPath("/WEB-INF/conf/Tview.properties")));

    }
    catch (IOException e)
    {
        System.out.println("Exception in getBankConfigProps: " + e);
    }
    return config;
    }

    public String getTabGroup(String groupName, String ldapGroups)
    {
    String grps[] = ldapGroups.split("cn=");
    String  tmpGroup = null;
    for (int i = 0; i < grps.length; i++)
    {
        if (grps[i] == null || grps[i].equals(""))
        continue;
        tmpGroup = grps[i].substring(0, grps[i].indexOf(","));
        System.out.println(tmpGroup);
        if (tmpGroup.equalsIgnoreCase(groupName))
        {
        System.out.println("Tableau Group of the user tmpGroup IS:" + tmpGroup);
        return tmpGroup;
        }
    }
    return "-";
    }

}

Create Properties file :
WEB-INF/conf/Tview.properties location:

Properties file contains:

TableauServerURL=domain name or IPAdress
displayParam=:embed=yes&:toolbar=yes

Create Jsp File named as report.jsp:

<html>
<%
String svr=(String)request.getAttribute("tabserverip");
String repUrl=(String)request.getAttribute("url");
String userid=(String)request.getAttribute("userid");
String groupid=(String)request.getAttribute("groupid");
System.out.println("tabserverip is: "+svr);
System.out.println("url is: "+repUrl);
System.out.println("userid is: "+userid);
System.out.println("groupid is: "+groupid);

String jscriptUrl="https://" + svr + "/javascripts/api/viz_v1.js";
System.out.println("jscriptUrl is: "+jscriptUrl);

%>

<script type="text/javascript" src="<%=jscriptUrl%>"></script>
<object class="tableauViz" width="100%" height="100%" style="display:none;">
<param name="path" value="<%=repUrl%>" />
<param name="filter" value="InsightID=<%=userid%>"/>
   </object>
</html>



 Create JSP file named as norights.jsp:

<html>
<p>
    <b><center><font name="ariel" size="3">You are not authorized.</font></center></b>
</p>
</html>

web.xml

    <servlet>
    <servlet-name>tview</servlet-name>
    <servlet-class>
            com.tview.TableauAuthServlet
    </servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>tview</servlet-name>
    <url-pattern>/tview</url-pattern>
  </servlet-mapping>


Simple DateFormat: JSP


Simple DateFormat:

<%@ page  language="java" import="java.text.DateFormat, java.text.SimpleDateFormat, java.util.Calendar" errorPage="" %>
 <%
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
Calendar calendar = Calendar.getInstance();
String currDate = df.format(calendar.getTime());
calendar.add(Calendar.DATE, -7);
String prevDate = df.format(calendar.getTime());
%>

 Previous Date IS: <%=prevDate%>"/> <br>
Current Date Is:  <%=currDate%>"/>

06 September, 2013

An error occurred communicating with the server (403) in Tableau.

Follow the below steps to prevent the network error in Tableau server:


“An error occurred communicating with the server (403). This may be a temporary network condition. Please retry the operation if this condition persists, contact your system administrator.”

This issue can occur if trusted authentication has been set up for Tableau Server. Beginning with version 8, security enhancements have been made to help protect your data from unauthorized access and other vulnerabilities. One of these enhancements includes added protection against tampering with VizQL sessions, which contain the sensitive data displayed in your view. Depending on your environment, you may not need this added level of protection. This may be true for environments where Tableau Server has been configured to use trusted authentication. In cases like this, as a Tableau Server administrator, you can disable this added security level to help resolve the above error.

Step 1

Click the Start button.

Step 2

In the search box, type Command Prompt. In the list of results, right-click Command Prompt, and click Run as administrator

Step 3

In the Command Prompt dialog box, change folders to the “bin” folder in the Tableau Server directory. For example, type one of the following commands depending on your machine:
  • For a 32-bit machine: cd “c:\Program Files\Tableau\Tableau Server\[version]\bin”
  • For a 64-bit machine: cd “c:\Program Files (x86)\Tableau\Tableau Server\[version]\bin”

Note: Replace [version] with the version of Tableau Server running on your machine.

Step 4

Type the following commands:  
  1. tabadmin stop
  2. tabadmin set vizqlserver.protect_sessions false
  3. tabadmin configure
  4. tabadmin start
Alternate Search Terms: trusted auth, 403, error

02 September, 2013

SSL Configuration For Tableau Server.

Follow the steps below to configure Tableau Server to use SSL.
  1. Acquire an Apache SSL certificate from a trusted authority (e.g., Verisign, Thawte, Comodo, GoDaddy, etc.). You can also use an internal certificate issued by your company. Wildcard certificates, which allow you to use SSL with many host names within the same domain, are also supported.
    Some browsers will require additional configuration to accept certificates from certain providers. Refer to the documentation provided by your certificate authority.
  2. Place the certificate files in a folder named SSL, parallel to the Tableau Server 7.0 folder. For example:
    C:\Program Files (x86)\Tableau\Tableau Server\SSL
    This location gives the account that's running Tableau Server the necessary permissions for the files.
  3. Open the Tableau Server Configuration Utility by selecting Start > All Programs > Tableau Server 8.0 > Configure Tableau Server on the Start menu.
  4. In the Configuration Tableau Server dialog box, select the SSL tab.
  5. Select Use SSL for Server Communication and provide the location for each of the following certificate files:
    • SSL Certificate File—Must be a valid PEM-encoded x509 certificate with the extension .crt
    • SSL Certificate Key File—Must be a valid RSA or DSA key that is not password protected with the file extension .key
    • SSL Certificate Chain File (Optional)—Some certificate providers issue two certificates for Apache. The second certificate is a chain file, which is a concatenation of all the certificates that form the certificate chain for the server certificate. All certificates in the file must be x509 PEM-encoded and the file must have a .crt extension (not .pem).

  6. Click OK. The changes will take effect the next time the server is restarted.
    When the server is configured for SSL, it accepts requests to the non-SSL port (default is port 80) and automatically redirects to the SSL port 443. SSL errors are logged in the install directory at the following location. Use this log to troubleshoot validation and encryption issues.
    C:\ProgramData\Tableau\Tableau Server\data\tabsvc\logs\httpd\error.log
    
    Note:
    Tableau Server only supports port 443 as the secure port. It cannot run on a machine where any other application is using port 443.