(JAVA WEB应用+Tableau JavaScript API)
Tableau已经被广泛地嵌入到到企业的内部站点或者业务系统中,嵌入Tableau的访问实际上对Tableau server的授权访问。其中有一个特别重要的需求,就是如何避免客户登录两次(业务系统登录+Tableau嵌入式系统登录)。
因此,我们需要在网页或者web应用程序验证阶段,设置受信任的身份验证,避免server对访问用户的二次验证。
【Dec 2, 2019】今天给客户的回复,用于排查相关问题:
大家好,我看了发了的java脚本,请按照顺序检查,从而排除问题:
- 1、脚本中有使用了一个用户,名字叫做 useruser,需要在server中有同名的账号,站点角色配置为explorer,
- 2、把传递ticket的域名地址,改为ip地址,即test.*****.com,改为10.**.0.39; 然后再用完整的地址测试;
- 3、浏览器只支持IE 11以上,不支持兼容模式,或者chrome,Firefox;需要确认是否打开了第三方cookies,必须使用cookies;
- 3、如果依然不行,使用后面我发的测试html,输入相关信息,查看报错信息,然后根据官方提示排查。
- 测试HTML: test-ticket.html
原理
实现方法
1、添加服务器信任
把web服务器加到Tableau server的受信任主机列表中,Tableau server对于web服务器的验证的信息不再做二次验证。因此,第一步是把web主机IP加入到Tableau server 的可信任列表中。可以通过界面添加(位置在 TSM后台-配置),也可以通过CLI命令来做。
通过tsm管理web添加:登录TSM,在“配置”选项卡上单击“用户身份和访问”,然后单击“受信任的身份验证”,为每个受信任的主机输入名称或 IP 地址,然后单击“添加”。
参考文档:
https://onlinehelp.tableau.com/current/server/zh-cn/trusted_auth_trustIP.htm
2 服务端获取票证,以此通行,免除二次验证
此处的关键,配置Web 服务器通过 POST 请求从 Tableau Server 获取票证(图中的步骤 3)
这里有几步,先把post请求发送到Tableau server,
private String getTrustedTicket(String SERVERHOST,String SERVERPORT, String userName) throws ServletException {
PrintWriter out = null;
BufferedReader in = null;
try {
String str=”http://”+SERVERHOST+”:”+SERVERPORT+”/trusted”;
// Send the request
URL url = new URL(str);
URLConnection conn = url.openConnection();
conn.setRequestProperty(“accept”, “*/*”);
conn.setRequestProperty(“connection”, “Keep-Alive”);
conn.setRequestProperty(“user-agent”, “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)”);
conn.setDoOutput(true);
conn.setDoInput(true);
out = new PrintWriter(conn.getOutputStream());
out.print(“username=” + userName);
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);
}
logger.info(“ticket:<” + rsp.toString() + “>”);
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) {
}
}
}
3 客户端页面
使用div 嵌入一个Tableau页面到现有的web应用程序中。
var containerDiv = document.getElementById(“vizContainer”),
url = “http://” + data[“host”] + “:” + data[“port”] + “/trusted/” + data[“ticket”] + “/views/” + data[“views”],
options = {
hideTabs: true,
hideToolbar: false,
onFirstInteractive: function () {
console.log(“Run this code when the viz has finished loading.”);
setInterval(refreshReport, 60*1000);
}
};
var viz = new tableau.Viz(containerDiv, url, options);
// Create a viz object and embed it in the container div.
官方的实例如下:For example
var placeholderDiv = document.getElementById("tableauViz");
var url = "http://tabserver/trusted/Etdpsm_Ew6rJY-9kRrALjauU/views/workbookname/viewname";
var options = {
hideTabs: true,
width: "800px",
height: "700px"
};
var viz = new tableau.Viz(placeholderDiv, url, options);
参考文档:
https://onlinehelp.tableau.com/current/api/js_api/en-us/JavaScriptAPI/js_api.htm
完整的示例文件:
<!DOCTYPE html>
<html>
<head>
<title>Basic Embed</title>
https://upublic.tableau.com/j/uavascripts/api/tableau-2.min.js
function initViz() {
var containerDiv = document.getElementById(“vizContainer”),
url = “http://public.tableau.com/views/RegionalSampleWorkbook/Storms“,
options = {
hideTabs: true,
onFirstInteractive: function () {
console.log(“Run this code when the viz has finished loading.”);
}
};
var viz = new tableau.Viz(containerDiv, url, options);
// Create a viz object and embed it in the container div.
}
</head>
<body onload=”initViz();”>
</body>
</html>
样例效果:
4、日志
如果有错误,建议去服务器查看日志。
ticket错误确切原因将写入到以下文件夹内的 vizqlserver_node*-*.log.* 文件中:
/var/opt/tableau/tableau_server/data/tabsvc/logs/vizqlserver
感谢 莱商银行罗经理对本文的贡献,本文还在更新中
May 23, 2019
Dec 2, 2019 update