为匿名(未注册)用户嵌入 QuickSight 视觉对象 - Amazon QuickSight

为匿名(未注册)用户嵌入 QuickSight 视觉对象

 适用于:企业版 
   目标受众:Amazon QuickSight 开发人员 

在以下各节中,您可以了解有关如何为匿名(未注册)用户设置嵌入式 Amazon QuickSight 视觉对象的详细信息。

步骤 1:设置权限

 适用于:企业版 
   目标受众:Amazon QuickSight 开发人员 

在下节中,您可以了解如何设置后端应用程序或 Web 服务器的权限。该任务需要具有 IAM 的管理访问权限。

访问视觉对象的每个用户代入一个角色,该角色向其授予 Amazon QuickSight 访问权限和视觉对象权限。要实现该目的,请在您的 AWS 账户 中创建一个 IAM 角色。将一个 IAM policy 与该角色相关联,以便为担任该角色的任何用户提供权限。

您可以在 IAM policy 中创建一个条件,限制开发人员可以在 GenerateEmbedUrlForAnonymousUser API 操作的 AllowedDomains 参数中列出的域。AllowedDomains 参数是可选参数。该参数允许您以开发人员身份覆盖在管理 QuickSight菜单中配置的静态域。您最多可以列出三个可以访问生成的 URL 的域或子域。然后,此 URL 将嵌入您创建的网站。只有参数中列出的域才能访问嵌入式控制面板。如果没有此条件,则可以在 AllowedDomains 参数中列出互联网上的任何域。

要限制开发人员可用于此参数的域,请在 IAM policy 中添加一个 AllowedEmbeddingDomains 条件。有关 AllowedDomains 参数的更多信息,请参阅《Amazon QuickSight API Reference》中的 GenerateEmbedUrlForAnonymousUser

以下示例策略提供了可用于 GenerateEmbedUrlForAnonymousUser 的这些权限。要让这种方法发挥作用,您的 AWS 账户 还需要会话包或会话容量定价。否则,当用户尝试访问视觉对象时,会返回 UnsupportedPricingPlanException 错误。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "quicksight:GenerateEmbedUrlForAnonymousUser" ], "Resource": [ "arn:{{partition}}:quicksight:{{region}}:{{accountId}}:namespace/{{namespace}}", "arn:{{partition}}:quicksight:{{region}}:{{accountId}}:dashboard/{{dashboardId-1}}", "arn:{{partition}}:quicksight:{{region}}:{{accountId}}:dashboard/{{dashboardId-2}}" ], "Condition": { "ForAllValues:StringEquals": { "quicksight:AllowedEmbeddingDomains": [ "https://my.static.domain1.com", "https://*.my.static.domain2.com" ] } } } }

您应用程序的 IAM 身份必须具有关联的信任策略,才允许访问您刚创建的角色。这意味着,在用户访问您的应用程序时,您的应用程序可以代表用户代入该角色打开视觉对象。下面演示了一个示例信任策略。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowLambdaFunctionsToAssumeThisRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Sid": "AllowEC2InstancesToAssumeThisRole", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

有关信任策略的更多信息,请参阅《IAM 用户指南》中的 IAM 临时安全凭证

步骤 2:生成附带身份验证代码的 URL

 适用于:企业版 
   目标受众:Amazon QuickSight 开发人员 

在下节中,您可以了解如何代表匿名访问者进行身份验证,并获取应用程序服务器上的可嵌入视觉对象 URL。

用户访问您的应用程序时,该应用程序代表用户代入 IAM 角色。然后,其会将用户添加到 QuickSight 中(如果该用户尚不存在)。接下来,其会将标识符作为唯一角色会话 ID 进行传递。

以下示例展示了代表用户执行 IAM 身份验证。将标识符作为唯一角色会话 ID 进行传递。此代码在您的应用程序服务器上运行。

import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.quicksight.AmazonQuickSight; import com.amazonaws.services.quicksight.AmazonQuickSightClientBuilder; import com.amazonaws.services.quicksight.model.AnonymousUserDashboardVisualEmbeddingConfiguration; import com.amazonaws.services.quicksight.model.AnonymousUserEmbeddingExperienceConfiguration; import com.amazonaws.services.quicksight.model.DashboardVisualId; import com.amazonaws.services.quicksight.model.GenerateEmbedUrlForAnonymousUserRequest; import com.amazonaws.services.quicksight.model.GenerateEmbedUrlForAnonymousUserResult; import com.amazonaws.services.quicksight.model.SessionTag; import java.util.List; /** * Class to call QuickSight AWS SDK to get url for Visual embedding. */ public class GenerateEmbedUrlForAnonymousUserTest { private final AmazonQuickSight quickSightClient; public GenerateEmbedUrlForAnonymousUserTest() { this.quickSightClient = AmazonQuickSightClientBuilder .standard() .withRegion(Regions.US_EAST_1.getName()) .withCredentials(new AWSCredentialsProvider() { @Override public AWSCredentials getCredentials() { // provide actual IAM access key and secret key here return new BasicAWSCredentials("access-key", "secret-key"); } @Override public void refresh() { } } ) .build(); } public String getEmbedUrl( final String accountId, // AWS Account ID final String namespace, // Anonymous embedding required specifying a valid namespace for which you want the enbedding URL final List<String> authorizedResourceArns, // Dashboard arn list of dashboard visuals to embed final String dashboardId, // Dashboard ID of the dashboard to embed final String sheetId, // Sheet ID of the sheet to embed final String visualId, // Visual ID of the visual to embed final List<String> allowedDomains, // Runtime allowed domains for embedding final List<SessionTag> sessionTags // Session tags used for row-level security ) throws Exception { final DashboardVisualId dashboardVisual = new DashboardVisualId() .withDashboardId(dashboardId) .withSheetId(sheetId) .withVisualId(visualId); final AnonymousUserDashboardVisualEmbeddingConfiguration anonymousUserDashboardVisualEmbeddingConfiguration = new AnonymousUserDashboardVisualEmbeddingConfiguration() .withInitialDashboardVisualId(dashboardVisual); final AnonymousUserEmbeddingExperienceConfiguration anonymousUserEmbeddingExperienceConfiguration = new AnonymousUserEmbeddingExperienceConfiguration() .withDashboardVisual(anonymousUserDashboardVisualEmbeddingConfiguration); final GenerateEmbedUrlForAnonymousUserRequest generateEmbedUrlForAnonymousUserRequest = new GenerateEmbedUrlForAnonymousUserRequest() .withAwsAccountId(accountId) .withNamespace(namespace) // authorizedResourceArns should contain ARN of dashboard used below in ExperienceConfiguration .withAuthorizedResourceArns(authorizedResourceArns) .withExperienceConfiguration(anonymousUserEmbeddingExperienceConfiguration) .withAllowedDomains(allowedDomains) .withSessionTags(sessionTags) .withSessionLifetimeInMinutes(600L); final GenerateEmbedUrlForAnonymousUserResult generateEmbedUrlForAnonymousUserResult = quickSightClient.generateEmbedUrlForAnonymousUser(generateEmbedUrlForAnonymousUserRequest); return generateEmbedUrlForAnonymousUserResult.getEmbedUrl(); } }
global.fetch = require('node-fetch'); const AWS = require('aws-sdk'); function generateEmbedUrlForAnonymousUser( accountId, // Your AWS account ID dashboardId, // Dashboard ID to which the constructed url points sheetId, // Sheet ID to which the constructed url points visualId, // Visual ID to which the constructed url points quicksightNamespace, // valid namespace where you want to do embedding authorizedResourceArns, // dashboard arn list of dashboard visuals to embed allowedDomains, // runtime allowed domains for embedding sessionTags, // session tags used for row-level security generateEmbedUrlForAnonymousUserCallback, // success callback method errorCallback // error callback method ) { const experienceConfiguration = { "DashboardVisual": { "InitialDashboardVisualId": { "DashboardId": dashboardId, "SheetId": sheetId, "VisualId": visualId } } }; const generateEmbedUrlForAnonymousUserParams = { "AwsAccountId": accountId, "Namespace": quicksightNamespace, // authorizedResourceArns should contain ARN of dashboard used below in ExperienceConfiguration "AuthorizedResourceArns": authorizedResourceArns, "AllowedDomains": allowedDomains, "ExperienceConfiguration": experienceConfiguration, "SessionTags": sessionTags, "SessionLifetimeInMinutes": 600 }; const quicksightClient = new AWS.QuickSight({ region: process.env.AWS_REGION, credentials: { accessKeyId: AccessKeyId, secretAccessKey: SecretAccessKey, sessionToken: SessionToken, expiration: Expiration } }); quicksightClient.generateEmbedUrlForAnonymousUser(generateEmbedUrlForAnonymousUserParams, function(err, data) { if (err) { console.log(err, err.stack); errorCallback(err); } else { const result = { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": "*", // USE YOUR WEBSITE DOMAIN TO SECURE ACCESS TO THIS API "Access-Control-Allow-Headers": "Content-Type" }, "body": JSON.stringify(data), "isBase64Encoded": false } generateEmbedUrlForAnonymousUserCallback(result); } }); }
import json import boto3 from botocore.exceptions import ClientError import time # Create QuickSight and STS clients quicksightClient = boto3.client('quicksight',region_name='us-west-2') sts = boto3.client('sts') # Function to generate embedded URL for anonymous user # accountId: YOUR AWS ACCOUNT ID # quicksightNamespace: VALID NAMESPACE WHERE YOU WANT TO DO NOAUTH EMBEDDING # authorizedResourceArns: DASHBOARD ARN LIST TO EMBED # allowedDomains: RUNTIME ALLOWED DOMAINS FOR EMBEDDING # experienceConfiguration: DASHBOARD ID, SHEET ID and VISUAL ID TO WHICH THE CONSTRUCTED URL POINTS # Example experienceConfig -> 'DashboardVisual': { # 'InitialDashboardVisualId': { # 'DashboardId': 'dashboardId', # 'SheetId': 'sheetId', # 'VisualId': 'visualId' # } # }, # sessionTags: SESSION TAGS USED FOR ROW-LEVEL SECURITY def generateEmbedUrlForAnonymousUser(accountId, quicksightNamespace, authorizedResourceArns, allowedDomains, experienceConfiguration, sessionTags): try: response = quicksightClient.generate_embed_url_for_anonymous_user( AwsAccountId = accountId, Namespace = quicksightNamespace, AuthorizedResourceArns = authorizedResourceArns, AllowedDomains = allowedDomains, ExperienceConfiguration = experienceConfiguration, SessionTags = sessionTags, SessionLifetimeInMinutes = 600 ) return { 'statusCode': 200, 'headers': {"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type"}, 'body': json.dumps(response), 'isBase64Encoded': bool('false') } except ClientError as e: print(e) return "Error generating embeddedURL: " + str(e)

以下示例演示了可以在应用程序服务器上使用以生成嵌入式控制面板 URL 的 JavaScript(Node.js)。您可以在网站或应用程序中使用该 URL 以显示控制面板。

const AWS = require('aws-sdk'); const https = require('https'); var quicksightClient = new AWS.Service({ apiConfig: require('./quicksight-2018-04-01.min.json'), region: 'us-east-1', }); quicksightClient.generateEmbedUrlForAnonymousUser({ 'AwsAccountId': '111122223333', 'Namespace' : 'default', // authorizedResourceArns should contain ARN of dashboard used below in ExperienceConfiguration 'AuthorizedResourceArns': authorizedResourceArns, 'ExperienceConfiguration': { 'DashboardVisual': { 'InitialDashboardVisualId': { 'DashboardId': 'dashboard_id', 'SheetId': 'sheet_id', 'VisualId': 'visual_id' } } }, 'AllowedDomains': allowedDomains, 'SessionTags': sessionTags, 'SessionLifetimeInMinutes': 600 }, function(err, data) { console.log('Errors: '); console.log(err); console.log('Response: '); console.log(data); });
//The URL returned is over 900 characters. For this example, we've shortened the string for //readability and added ellipsis to indicate that it's incomplete. { "Status": "200", "EmbedUrl": "https://quicksightdomain/embed/12345/dashboards/67890/sheets/12345/visuals/67890...", "RequestId": "7bee030e-f191-45c4-97fe-d9faf0e03713" }

以下示例演示了可以在应用程序服务器上使用以生成嵌入式控制面板 URL 的 .NET/C# 代码。您可以在网站或应用程序中使用该 URL 以显示控制面板。

using System; using Amazon.QuickSight; using Amazon.QuickSight.Model; namespace GenerateDashboardEmbedUrlForAnonymousUser { class Program { static void Main(string[] args) { var quicksightClient = new AmazonQuickSightClient( AccessKey, SecretAccessKey, SessionToken, Amazon.RegionEndpoint.USEast1); try { DashboardVisualId dashboardVisual = new DashboardVisualId { DashboardId = "dashboard_id", SheetId = "sheet_id", VisualId = "visual_id" }; AnonymousUserDashboardVisualEmbeddingConfiguration anonymousUserDashboardVisualEmbeddingConfiguration = new AnonymousUserDashboardVisualEmbeddingConfiguration { InitialDashboardVisualId = dashboardVisual }; AnonymousUserEmbeddingExperienceConfiguration anonymousUserEmbeddingExperienceConfiguration = new AnonymousUserEmbeddingExperienceConfiguration { DashboardVisual = anonymousUserDashboardVisualEmbeddingConfiguration }; Console.WriteLine( quicksightClient.GenerateEmbedUrlForAnonymousUserAsync(new GenerateEmbedUrlForAnonymousUserRequest { AwsAccountId = "111222333444", Namespace = default, // authorizedResourceArns should contain ARN of dashboard used below in ExperienceConfiguration AuthorizedResourceArns = { "dashboard_id" }, ExperienceConfiguration = anonymousUserEmbeddingExperienceConfiguration, SessionTags = sessionTags, SessionLifetimeInMinutes = 600, }).Result.EmbedUrl ); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }

要担任该角色,请选择以下 AWS Security Token Service (AWS STS) API 操作之一:

  • AssumeRole – 在使用 IAM 身份代入角色时使用此操作。

  • AssumeRoleWithWebIdentity – 在使用 Web 身份提供者对用户进行身份验证时使用此操作。

  • AssumeRoleWithSaml – 在使用安全断言标记语言(SAML)对用户进行身份验证时使用此操作。

以下示例显示了用于设置 IAM 角色的 CLI 命令。该角色需要为 quicksight:GenerateEmbedUrlForAnonymousUser 启用权限。

aws sts assume-role \ --role-arn "arn:aws:iam::11112222333:role/QuickSightEmbeddingAnonymousPolicy" \ --role-session-name anonymous caller

assume-role 操作返回三个输出参数:访问密钥、私有密钥和会话令牌。

注意

如果在调用 AssumeRole 操作时遇到 ExpiredToken 错误,可能是因为之前的 SESSION TOKEN 仍在环境变量中。通过设置以下变量可以解决这一问题:

  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY

  • AWS_SESSION_TOKEN

以下示例说明了如何在 CLI 中设置这三个参数。如果使用的是 Microsoft Windows 计算机,请使用 set 而非 export

export AWS_ACCESS_KEY_ID = "access_key_from_assume_role" export AWS_SECRET_ACCESS_KEY = "secret_key_from_assume_role" export AWS_SESSION_TOKEN = "session_token_from_assume_role"

如果运行这些命令,则会将访问您的网站的用户的角色会话 ID 设置为 embedding_quicksight_visual_role/QuickSightEmbeddingAnonymousPolicy。角色会话 ID 由 role-arn 中的角色名称和 role-session-name 值组成。每个用户使用唯一的角色会话 ID 可以确保为每个访问用户设置相应的权限。其还能让每个会话保持独立性和独特性。如果您使用一组 Web 服务器(例如用于负载平衡),并且会话重新连接到其他服务器,则会开始新的会话。

要获取视觉对象的签名 URL,请从应用程序服务器中调用 generate-embed-url-for-anynymous-user。这会返回可嵌入视觉对象 URL。以下示例演示了如何使用服务器端调用为匿名访问您 Web 门户或应用的用户生成嵌入式视觉对象的 URL。

aws quicksight generate-embed-url-for-anonymous-user \ --aws-account-id 111122223333 \ --namespace default-or-something-else \ --session-lifetime-in-minutes 15 \ --authorized-resource-arns '["dashboard-arn-1","dashboard-arn-2"]' \ --allowed-domains '["domain1","domain2"]' \ --session-tags '["Key": tag-key-1,"Value": tag-value-1,{"Key": tag-key-1,"Value": tag-value-1}]' \ --experience-configuration 'DashboardVisual={InitialDashboardVisualId={DashboardId=dashboard_id,SheetId=sheet_id,VisualId=visual_id}}'

有关使用此操作的更多信息,请参阅 GenerateEmbedUrlForAnonymousUser。您可以在自己的代码中使用该 API 操作和其他操作。

步骤 3:嵌入视觉对象 URL

 适用于:企业版 
   目标受众:Amazon QuickSight 开发人员 

在下节中,您可以了解如何使用 QuickSight Embedding SDK(JavaScript)将步骤 2 中的视觉对象 URL 嵌入网站或应用程序页面。通过使用该开发工具包,您可以执行以下操作:

  • 将视觉对象置于 HTML 页面上。

  • 将参数传入视觉对象。

  • 使用为应用程序自定义的消息处理错误状态。

调用 GenerateEmbedUrlForAnonymousUser API 操作生成可嵌入应用的 URL。该 URL 的有效期为 5 分钟,生成的会话的有效期为 10 个小时。该 API 操作为 URL 提供授权(auth)代码以启用单点登录会话。

下面显示了 generate-embed-url-for-anonymous-user 的示例响应:此示例中的 quicksightdomain 是用来访问 QuickSight 账户的 URL。

//The URL returned is over 900 characters. For this example, we've shortened the string for //readability and added ellipsis to indicate that it's incomplete. { "Status": "200", "EmbedUrl": "https://quicksightdomain/embed/12345/dashboards/67890/sheets/12345/visuals/67890...", "RequestId": "7bee030e-f191-45c4-97fe-d9faf0e03713" }

通过使用 QuickSight Embedding SDK 或将该 URL 添加到 iframe 中,将该视觉对象嵌入网页。如果设置了固定高度和宽度数字(以像素为单位),QuickSight 将使用这些数字,并且在调整窗口大小时不会更改视觉对象。如果设置了相对百分比高度和宽度,QuickSight 将提供随窗口大小变化而修改的响应式布局。通过使用 QuickSight Embedding SDK,您还可以控制视觉对象中的参数,并在视觉对象加载完成和出现错误时收到回调。

要托管嵌入式视觉对象的域必须位于允许列表(为您的 Amazon QuickSight 订阅批准的域的列表)中。这一要求可阻止未经批准的域托管嵌入式视觉对象和控制面板,从而保护您的数据。有关为嵌入式视觉对象和控制面板添加域的更多信息,请参阅 允许在运行时使用 QuickSight API 列出域

以下示例演示了如何使用生成的 URL。此代码位于您的应用程序服务器上。

<!DOCTYPE html> <html> <head> <title>Visual Embedding Example</title> <script src="https://unpkg.com/amazon-quicksight-embedding-sdk@2.0.0/dist/quicksight-embedding-js-sdk.min.js"></script> <script type="text/javascript"> const embedVisual = async() => { const { createEmbeddingContext, } = QuickSightEmbedding; const embeddingContext = await createEmbeddingContext({ onChange: (changeEvent, metadata) => { console.log('Context received a change', changeEvent, metadata); }, }); const frameOptions = { url: "<YOUR_EMBED_URL>", // replace this value with the url generated via embedding API container: '#experience-container', height: "700px", width: "1000px", onChange: (changeEvent, metadata) => { switch (changeEvent.eventName) { case 'FRAME_MOUNTED': { console.log("Do something when the experience frame is mounted."); break; } case 'FRAME_LOADED': { console.log("Do something when the experience frame is loaded."); break; } } }, }; const contentOptions = { parameters: [ { Name: 'country', Values: ['United States'], }, { Name: 'states', Values: [ 'California', 'Washington' ] } ], locale: "en-US", onMessage: async (messageEvent, experienceMetadata) => { switch (messageEvent.eventName) { case 'CONTENT_LOADED': { console.log("All visuals are loaded. The title of the document:", messageEvent.message.title); break; } case 'ERROR_OCCURRED': { console.log("Error occured while rendering the experience. Error code:", messageEvent.message.errorCode); break; } case 'PARAMETERS_CHANGED': { console.log("Parameters changed. Changed parameters:", messageEvent.message.changedParameters); break; } case 'SIZE_CHANGED': { console.log("Size changed. New dimensions:", messageEvent.message); break; } } }, }; const embeddedVisualExperience = await embeddingContext.embedVisual(frameOptions, contentOptions); const selectCountryElement = document.getElementById('country'); selectCountryElement.addEventListener('change', (event) => { embeddedVisualExperience.setParameters([ { Name: 'country', Values: event.target.value } ]); }); }; </script> </head> <body onload="embedVisual()"> <span> <label for="country">Country</label> <select id="country" name="country"> <option value="United States">United States</option> <option value="Mexico">Mexico</option> <option value="Canada">Canada</option> </select> </span> <div id="experience-container"></div> </body> </html>
<!DOCTYPE html> <html> <head> <title>Visual Embedding Example</title> <!-- You can download the latest QuickSight embedding SDK version from https://www.npmjs.com/package/amazon-quicksight-embedding-sdk --> <!-- Or you can do "npm install amazon-quicksight-embedding-sdk", if you use npm for javascript dependencies --> <script src="./quicksight-embedding-js-sdk.min.js"></script> <script type="text/javascript"> let embeddedVisualExperience; function onVisualLoad(payload) { console.log("Do something when the visual is fully loaded."); } function onError(payload) { console.log("Do something when the visual fails loading"); } function embedVisual() { const containerDiv = document.getElementById("embeddingContainer"); const options = { url: "<YOUR_EMBED_URL>", // replace this value with the url generated via embedding API container: containerDiv, parameters: { country: "United States" }, height: "700px", width: "1000px", locale: "en-US" }; embeddedVisualExperience = QuickSightEmbedding.embedVisual(options); embeddedVisualExperience.on("error", onError); embeddedVisualExperience.on("load", onVisualLoad); } function onCountryChange(obj) { embeddedVisualExperience.setParameters({country: obj.value}); } </script> </head> <body onload="embedVisual()"> <span> <label for="country">Country</label> <select id="country" name="country" onchange="onCountryChange(this)"> <option value="United States">United States</option> <option value="Mexico">Mexico</option> <option value="Canada">Canada</option> </select> </span> <div id="embeddingContainer"></div> </body> </html>

要让此示例起作用,请确保使用 Amazon QuickSight Embedding SDK 在网站上用 JavaScript 加载嵌入式视觉对象。要获取副本,请执行下列操作之一: