配置 Tableau 已连接应用以启用嵌入内容的 SSO

从 Tableau Server 版本 2022.1 开始, Tableau 已连接应用通过促进您的 Tableau Server 站点与嵌入 Tableau 内容的外部应用程序之间建立明确的信任关系,实现无缝且安全的身份验证体验。在 Tableau Server 2022.3 中,Tableau 已连接应用扩展了其功能以支持 REST API 授权。并且从 Tableau Server 2023.3 开始,元数据 API 尊重通过已连接应用进行的 REST API 授权。

已连接应用提供以下好处:

  • 限制对哪些内容可以嵌入以及该内容可以嵌入的位置的访问
  • 为用户提供使用单点登录 (SSO) 访问嵌入内容的能力,而不必与身份提供程序 (IdP) 集成
  • 为用户提供直接从外部应用程序进行身份验证的能力
  • 使用 JSON Web 令牌 (JWT) 以编程方式代表用户授权访问 Tableau REST API(从 Tableau Server 2023.3 开始为元数据 API)

注意:

  • 在 Tableau Server 版本 2021.4 中,可通过 Tableau REST API 中的已连接应用方法(链接在新窗口中打开)使用无 UI 的已连接应用功能。
  • 若要通过已连接应用启用嵌入,必须将 Tableau Server 配置为对 HTTP 流量使用 SSL。
  • 为了使会话令牌有效,外部应用程序和托管外部应用程序的服务器的时钟必须设置为协调世界时 (UTC)。如果任何一个时钟使用不同的标准,连接的应用软件将不被信任。
  • Tableau 已连接应用和 Salesforce 已连接应用不同并且提供不同的功能。如今,Tableau 已连接应用已针对在外部应用程序中嵌入 Tableau 视图和指标进行了优化。(2023 年 10 月,Tableau 取消了将指标嵌入到 Tableau CloudTableau Server 版本 2023.3 的功能。)

已连接应用的工作方式

您的 Tableau Server 站点和外部应用程序之间的信任关系是通过 JSON 网络令牌 (JWT) 标准中的身份验证令牌建立和验证的,该令牌使用由 Tableau 已连接应用提供并由您的自定义应用程序签名的共享密文。

已连接应用的关键组件

已连接应用的以下组件与外部应用程序中的 JWT 一起工作,以验证用户身份并显示嵌入的内容。

  • 密文:密文是 Tableau 和您的外部应用程序共享的密钥。它们在形成 JWT 的签名中使用。使用已连接应用进行嵌入身份验证时需要密文。密文可以在已连接应用中创建,不会过期,并且在删除之前一直有效。
  • 域允许列表:您可以在每个已连接应用中指定允许的域的列表。通过已连接应用嵌入的 Tableau 内容仅允许在指定的域下使用。这有助于确保内容在您的企业保护和批准的域下公开。
  • 访问级别:您可以通过将已连接应用与一个项目或所有项目相关联来指定可通过已连接应用嵌入哪些内容。如果指定一个项目,则只能通过已连接应用嵌入所选项目中的内容。

已连接应用工作流程

下图说明了外部应用程序(Web 服务器及网页)和已连接应用之间的身份验证工作方式。

  1. 用户访问网页:当用户访问网页上的嵌入内容时,网页会向您的外部应用程序发送 GET 请求以检索该网页上的 HTML。
  2. 外部应用程序构建身份验证令牌:外部应用程序构建 JWT,其中包含来自已连接应用的密文(有关其他 JWT 要求,请参见下面的“步骤 3”)以及用户对嵌入内容的访问范围。该密文由外部应用程序签名,用于后续步骤中的信任关系验证。
  3. 外部应用程序使用身份验证令牌响应:外部应用程序使用网页调用的嵌入内容 URL 中的 JWT 响应页面。
  4. 网页从 Tableau 请求内容:尝试加载嵌入内容时,网页调用嵌入内容的 URL,后者向 Tableau 发送 GET 请求。
  5. Tableau 验证令牌: Tableau 接收 JWT 并通过识别 JWT 中使用的已连接应用和共享密文来验证与外部应用程序的信任关系。然后 Tableau 为用户创建一个会话。会话不仅遵守 JWT 中定义的嵌入范围,还遵守已连接应用中指定的限制,包括允许的域和允许的项目。
  6. Tableau 根据受限制的嵌入上下文返回内容:嵌入的内容仅在页面位于允许的域下并且内容发布到允许的项目(如果适用)时加载。经过身份验证的用户只能通过 JWT 中定义的范围与嵌入的内容进行交互。

创建已连接应用

步骤 1:创建已连接应用

Tableau Server 的“设置”页面创建已连接应用。

  1. 以服务器管理员身份登录 Tableau Server

  2. 从左侧窗格中,选择“设置”>“已连接应用”,然后单击“新建已连接应用”按钮。

  3. 在“创建已连接应用”对话框中,执行以下操作之一:
    1. 对于REST API 授权工作流(包括使用 REST API 进行身份验证的元数据 API 工作流),在“已连接应用名称”文本框中,输入已连接应用的名称,然后单击“创建”按钮。

      注意:在为 REST API 和元数据 API 授权配置已连接应用时,您可以忽略“访问级别”“域允许列表”

    2. 对于嵌入工作流,请执行以下操作:

      1. 在“已连接应用名称”文本框中,输入已连接应用的名称。

      2. 从“应用于”下拉菜单中,选择“所有项目”“仅一个项目”来控制可以嵌入哪些视图或指标。如果您选择“仅一个项目”选项,请选择要确定范围的特定项目。有关这两个选项的详细信息,请参见访问级别(仅限嵌入工作流)

        注意:

      3. 在“域允许列表”中,使用下面的域格式设置中描述的规则指定域,以控制可以嵌入视图或指标的位置。

      4. 完成后,单击“创建”按钮。

  4. 在已连接应用的名称旁边,单击操作菜单并选择“启用”。出于安全考虑,已连接应用在创建时默认设置为禁用。

  5. 记下已连接应用的 ID(也称为客户端 Id),以在下面的“步骤 3”中使用。

步骤 2:生成密文

您可以为每个已连接应用生成总共两个密文。第二个密文可用于密文轮换目的,以帮助防止密文泄露时出现问题。

  1. 在您在“步骤 1”中创建的已连接应用的详细信息页面上,单击“生成新密文”按钮。

  2. 记下要在下面的“步骤 3”中使用的密文 ID 和密文值。

步骤 3:配置 JWT

生成密文后,您希望使外部应用程序能够发送有效的 JWT。JWT 是用于在两方之间安全传输信息的标准。JWT 由您的外部应用程序签名,以安全地将信息发送到 Tableau Server。JWT 引用已连接应用、为其生成会话的用户以及用户应具有的访问级别。

有效的 JWT 包括以下信息:

  • 来自“步骤 1”的已连接应用 ID(也称为客户端 ID)
  • “步骤 2”中生成的密文 ID 和密文值

  • 注册的声明和标题:

    声明名称描述或必需值
    kid密文 ID必需(在标题中)。已连接应用密文 ID。
    iss颁发者必需(在标题中)。标识受信任的已连接应用及其签名密钥的唯一颁发者 URI。
    alg算法必需(在标题中)。JWT 签名算法。仅支持 HS256。
    sub使用者经过身份验证的 Tableau Server 用户的。
    aud受众值必须是:“tableau”。
    exp到期时间

    有效的 JWT 不得过期。JWT 的过期时间必须在配置的最长有效期内。可以使用 tsmvizportal.oauth.connected_apps.max_expiration_period_in_minutes命令配置最长有效期。

    jtiJWT ID要求采用声明形式。JWT ID 声明为 JWT 提供唯一标识符,并且区分大小写。
    scp

    重要:不要使用“scope”。

    范围对于嵌入工作流,支持的值包括:

    tableau:views:embed
    tableau:views:embed_authoring”(Tableau Server 2022.3 中新增)
    tableau:metrics:embed”(在 Tableau Server 2023.3 中停用
    tableau:ask_data:embed”(Tableau Server 版本 2023.1 中新增)

    注意:

    • 值必须作为列表类型传递。
    • 对于 tableau:views:embed,范围遵循已在 Tableau Server 中配置的用户权限,并允许用户与嵌入视图中的工具进行交互(如果在原始视图中可用)。
    • 我们建议嵌入代码排除工具栏参数。有关详细信息,请参见下面的已知问题(仅限嵌入工作流)

    对于 REST API 授权工作流,请参见支持 JWT 授权的 REST API 方法

    对于使用 REST API 进行身份验证的元数据 API 工作流,唯一支持的范围是 tableau:content:read

示例 JWT

以下是 Java 和 Python 语言的示例 JWT。Java 和 Python 示例分别使用 nimbus-jose-jwt 库和 PyJWT 库。

Java

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.*;
import com.nimbusds.jwt.*;

import java.util.*;

...
				
String secret = "secretvalue";
	String kid = "connectedAppSecretId";
	String clientId = "connectedAppClientId";
	List<String> scopes = new
ArrayList<>(Arrays.asList("tableau:views:embed"));
	String username = "username";
	JWSSigner signer = new MACSigner(secret);
	JWSHeader header = new
JWSHeader.Builder(JWSAlgorithm.HS256).keyID(kid).customParam("iss", clientId).build();
	JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
		.issuer(clientId)
		.expirationTime(new Date(new Date().getTime() + 60 * 1000)) //expires in 1 minute
		.jwtID(UUID.randomUUID().toString())
		.audience("tableau")
		.subject(username)
		.claim("scp", scopes)
		.build();
	SignedJWT signedJWT = new SignedJWT(header, claimsSet);
	signedJWT.sign(signer);
	model.addAttribute("token", signedJWT.serialize());

Python

import jwt
token = jwt.encode(
	{
		"iss": connectedAppClientId,
		"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=5),
		"jti": str(uuid.uuid4()),
		"aud": "tableau",
		"sub": user,
		"scp": ["tableau:views:embed", "tableau:metrics:embed"]
	},
		connectedAppSecretKey,
		algorithm = "HS256",
		headers = {
		'kid': connectedAppSecretId,
		'iss': connectedAppClientId
        }
  )

配置 JWT 后,当代码由您的外部应用程序运行时,它将生成一个令牌。

步骤 4:后续步骤

对于嵌入工作流

配置 JWT 后,您必须向外部应用程序中添加嵌入代码。确保在外部应用程序调用的 Web 组件中包含您在上述“步骤 3”中配置的有效 JWT。

有关嵌入 Tableau 内容的详细信息,请参见以下一项或两项:

注意:为了让用户在访问嵌入式内容时成功进行身份验证,浏览器必须配置为允许第三方 Cookie。

对于 REST API 授权工作流

配置 JWT 后,您必须将有效的 JWT 添加到 REST API 登录请求以进行授权访问。有关详细信息,请参见已连接应用的访问范围

对于元数据 API 工作流

配置 JWT 后,您必须将有效的 JWT 添加到 REST API 登录请求。有关详细信息,请参见已连接应用的访问范围

管理已连接应用

您可以在“已连接应用”页面上管理站点的所有已连接应用。您可以执行诸如以下任务:创建、删除和禁用已连接应用;以及在现有密文已泄露的情况下撤销或生成新密文。

  1. 以服务器管理员或站点管理员身份登录 Tableau Server

  2. 从左侧窗格中,选择“设置”>“已连接应用”

  3. 选中您要管理的已连接应用旁边的复选框,然后执行以下一项或多项操作:

    • 根据您组织的安全策略指定的轮换时间线生成新密文。若要生成额外的密文,请单击已连接应用的名称,然后单击“生成新密文”按钮。一个已连接应用最多可以有两个密文。这两个密文可以同时处于活动状态,不会过期,并且在被删除之前一直有效。

    • 通过单击已连接应用的名称查看已连接应用的创建时间、其 ID、项目和域范围及其密文,查看已连接应用详细信息

    • 更改项目范围或域,在“操作”菜单中,选择“编辑”。进行更改并单击“更新”

      注意:如果您更改项目或域范围,并且新项目或新域中不存在嵌入的内容,则嵌入的视图或指标无法显示,用户在访问嵌入的内容时会看到错误。

    • 通过单击已连接应用的名称来删除密文。在已连接应用页面上,单击密文旁边的“操作”并选择“删除”。在确认对话框中,再次选择“删除”

      注意:如果外部应用程序正在使用已连接应用的密文,则删除密文后无法显示嵌入的视图或指标。有关详细信息,请参见下面的禁用或删除已连接应用或删除密文的影响

    • 禁用已连接应用,在“操作”菜单中,选择“禁用”。如果外部应用程序正在使用已连接应用,则在禁用已连接应用后无法显示嵌入的视图或指标。有关详细信息,请参见下面的禁用或删除已连接应用或删除密文的影响

禁用或删除已连接应用或删除密文的影响

若要通过已连接应用向您的用户显示嵌入式视图或指标,需要启用已连接应用并生成密文。如果已连接应用正在您的外部应用程序中使用并且被禁用或删除,或者其密文被删除或替换,则用户在访问嵌入内容时将收到错误。

为了避免此问题,请确保启用已连接应用并且 JWT 使用正确的密文 ID 和值。

访问级别(仅限嵌入工作流)

在配置已连接应用的访问级别时,您可以选择以下两个项目类型之一:访问级别控制可以嵌入哪些内容。

  • 所有项目:此选项允许嵌入所有项目中的内容。
  • 仅一个项目:此选项仅允许嵌入指定项目中的内容。如果指定的项目包含嵌套项目,则不会启用在这些嵌套项目中嵌入内容。

域允许列表规则(仅限嵌入工作流)

已连接应用的域允许列表使您能够将对嵌入式 Tableau 内容的访问限制为所有域或某些域;或者排除某些域或阻止所有域。

域选项

在配置已连接应用的域允许列表时,您可以选择以下两个选项之一:

  • 所有域:作为默认选项,此选项启用对嵌入内容的无限制访问。
  • 仅特定域:此选项使您能够缩小对嵌入内容的访问范围。如果使用此选项,请遵循下面的域格式设置部分指定的格式设置规则。

域格式设置

在域允许列表文本框中,您可以使用下面的格式示例输入一个或多个域。

注意:在 Tableau REST API 中使用已连接应用方法(链接在新窗口中打开)时,域格式设置规则也适用。

以下是一些基于常见场景的格式设置示例:

若要指定...示例嵌入访问
域范围*.myco.com可以从 myco.com 下的所有子域访问嵌入的内容。
所有端口myco.com:*可以通过 myco.com 的所有端口访问嵌入式内容。
特定端口myco.com:8080只能通过 myco.com 的 8080 端口访问嵌入式内容。
多个离散域myco.com
events.myco.com
ops.myco.com

嵌入的内容可从所有三个域访问。

注意:指定多个域时,请在新行中键入每个域,或使用空格将各个域分开。对于 REST API,域必须用空格分隔。

仅安全流量https:无论域如何,都可以安全地访问嵌入式内容。
进入一系列域的所有端口的安全流量https:*myco.com:*可以通过 myco.com 下的所有子域上的所有端口访问嵌入式内容。
没有域[没有域]对嵌入内容的访问被阻止。

已知问题(仅限嵌入工作流)

使用已连接应用时存在一些已知问题,这些问题将在未来版本中解决。

  • 工具栏功能:当嵌入式内容定义了工具栏参数时,并非所有工具栏功能都可以使用。为了解决此问题,我们建议您像下面的示例一样隐藏工具栏参数。

    <tableau-viz id='tab-viz' src='https://<your_server>/t/<your_site>/...'
    	toolbar='hidden'>
    </tableau-viz>

  • 已发布数据源:将不会显示设置为提示用户提供数据库凭据的已发布数据源。为了解决此问题,如果可能,我们建议数据源所有者改为嵌入他们的数据库凭据。
  • 嵌入式仪表板中的“数据问答”(Ask Data) 功能对象:不会加载嵌入式仪表板中的“数据问答”(Ask Data) 功能对象。(在 Tableau Server 2024.2 将停用“数据问答”(Ask Data) 功能。

  • 指标和域允许列表:尽管在已连接应用的域允许列表中可能指定了访问限制,嵌入式指标视图仍将显示。注意: 从嵌入式视图的工具栏访问的指标数据将按预期工作。(在 Tableau Server 2023.3 中,Tableau 停用了嵌入指标的功能。)

感谢您的反馈!您的反馈已成功提交。谢谢!