C# 嵌入角色的Power BI,允许行级安全
我已经从Github为您的客户实现了Microsoft Embed示例,该示例非常有效 我现在扩展它,有文章显示使用API的V1和V2都会导致相同的错误: 操作返回了无效的状态代码“BadRequest”C# 嵌入角色的Power BI,允许行级安全,c#,powerbi,powerbi-embedded,C#,Powerbi,Powerbi Embedded,我已经从Github为您的客户实现了Microsoft Embed示例,该示例非常有效 我现在扩展它,有文章显示使用API的V1和V2都会导致相同的错误: 操作返回了无效的状态代码“BadRequest” 在 Microsoft.PowerBI.Api.ReportsOperations.GenerateTokenInGroupWithHTTPMessageAsync(Guid groupId、Guid reportId、GenerateTokenRequest请求参数、, 字典'2 custo
在 Microsoft.PowerBI.Api.ReportsOperations.GenerateTokenInGroupWithHTTPMessageAsync(Guid groupId、Guid reportId、GenerateTokenRequest请求参数、, 字典'2 customHeaders,CancellationToken CancellationToken)
[HttpGet]
公共异步任务GetEmbedInfo()
{
尝试
{
//验证appsettings.json中是否提供了所有必需的配置
字符串configValidationResult=ConfigValidatorService.ValidateConfig(azureAd,powerBI);
if(configValidationResult!=null)
{
HttpContext.Response.StatusCode=400;
返回configValidationResult;
}
EmbeddeParams embeddeParams=wait pbiEmbedService.getEmbeddeParams(新Guid(powerBI.Value.WorkspaceId)、新Guid(powerBI.Value.ReportId));
//EmbeddeParams EmbeddeParams=await pbiEmbedService.GetEmbeddeToken4(新Guid(powerBI.Value.WorkspaceId)、新Guid(powerBI.Value.ReportId));
返回JsonSerializer.Serialize(embeddeparams);
}
捕获(例外情况除外)
{
HttpContext.Response.StatusCode=500;
返回ex.Message+“\n\n”+ex.StackTrace;
}
}
上面的代码将被调用,并根据演示进行调用
public async Task<EmbedParams> GetEmbedParams(Guid workspaceId, Guid reportId, [Optional] Guid additionalDatasetId)
{
PowerBIClient pbiClient = this.GetPowerBIClient();
// Get report info
var pbiReport = await pbiClient.Reports.GetReportInGroupAsync(workspaceId, reportId);
//var generateTokenRequestParameters = new GenerateTokenRequest("View", null, identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "**************", roles: new List<string> { "****", "****" }, datasets: new List<string> { "datasetId" }) });
//var tokenResponse = pbiClient.Reports.GenerateTokenInGroupAsync("groupId", "reportId", generateTokenRequestParameters);
// Create list of datasets
var datasetIds = new List<Guid>();
// Add dataset associated to the report
datasetIds.Add(Guid.Parse(pbiReport.DatasetId));
// Append additional dataset to the list to achieve dynamic binding later
if (additionalDatasetId != Guid.Empty)
{
datasetIds.Add(additionalDatasetId);
}
// Add report data for embedding
var embedReports = new List<EmbedReport>() {
new EmbedReport
{
ReportId = pbiReport.Id, ReportName = pbiReport.Name, EmbedUrl = pbiReport.EmbedUrl
}
};
// Get Embed token multiple resources
var embedToken = await GetEmbedToken4(workspaceId, reportId);
// Capture embed params
var embedParams = new EmbedParams
{
EmbedReport = embedReports,
Type = "Report",
EmbedToken = embedToken
};
return embedParams;
}
公共异步任务GetEmbedParams(Guid workspaceId、Guid reportId、[可选]Guid additionalDatasetId)
{
PowerBIClient pbiClient=this.GetPowerBIClient();
//获取报告信息
var pbiReport=await pbiClient.Reports.GetReportingGroupAsync(工作空间ID,reportId);
//var generateTokenRequestParameters=new GenerateTokenRequest(“视图”,null,标识:新列表{new EffectiveIdentity(用户名:*******************”,角色:新列表{“****”,“****”},数据集:新列表{“datasetId”});
//var tokenResponse=pbiClient.Reports.GenerateTokenInGroupAsync(“groupId”、“reportId”、generateTokenRequestParameters);
//创建数据集列表
var datasetIds=新列表();
//添加与报表关联的数据集
Add(Guid.Parse(pbiReport.DatasetId));
//将其他数据集附加到列表中,以便稍后实现动态绑定
if(additionalDatasetId!=Guid.Empty)
{
Add(additionalDatasetId);
}
//添加用于嵌入的报表数据
var embeddereports=新列表(){
新报告
{
ReportId=pbiReport.Id,ReportName=pbiReport.Name,EmbedUrl=pbiReport.EmbedUrl
}
};
//获取多个资源的嵌入令牌
var embedToken=wait GetEmbedToken4(工作空间ID、报告ID);
//捕获嵌入参数
var embedParams=新的embedParams
{
嵌入报告=嵌入报告,
Type=“报告”,
EmbeddeToken=EmbeddeToken
};
返回参数;
}
除了一行调用下一个方法的代码外,上面的代码是每个演示的代码:
var embedToken = await GetEmbedToken4(workspaceId, reportId);
public EmbedToken GetEmbedToken(Guid reportId, IList<Guid> datasetIds, [Optional] Guid targetWorkspaceId)
{
PowerBIClient pbiClient = this.GetPowerBIClient();
// Create a request for getting Embed token
// This method works only with new Power BI V2 workspace experience
var tokenRequest = new GenerateTokenRequestV2(
reports: new List<GenerateTokenRequestV2Report>() { new GenerateTokenRequestV2Report(reportId) },
datasets: datasetIds.Select(datasetId => new GenerateTokenRequestV2Dataset(datasetId.ToString())).ToList(),
targetWorkspaces: targetWorkspaceId != Guid.Empty ? new List<GenerateTokenRequestV2TargetWorkspace>() { new GenerateTokenRequestV2TargetWorkspace(targetWorkspaceId) } : null
);
// Generate Embed token
var embedToken = pbiClient.EmbedToken.GenerateToken(tokenRequest);
return embedToken;
}
var embeddetoken=wait getembeddetoken4(工作空间ID、报告ID);
公共EmbedToken GetEmbedToken(Guid reportId,IList datasetIds,[可选]Guid targetWorkspaceId)
{
PowerBIClient pbiClient=this.GetPowerBIClient();
//创建获取嵌入令牌的请求
//此方法仅适用于新的Power BI V2工作区体验
var tokenRequest=new GenerateTokenRequestV2(
报告:new List(){new GenerateTokenRequestV2Report(reportId)},
datasets:datasetId.Select(datasetId=>new GenerateTokenRequestV2Dataset(datasetId.ToString()).ToList(),
targetWorkspaces:targetWorkspaceId!=Guid.Empty?新建列表(){new GenerateTokenRequestV2TargetWorkspace(targetWorkspaceId)}:null
);
//生成嵌入令牌
var embedToken=pbiClient.embedToken.GenerateToken(令牌请求);
返回令牌;
}
以上代码符合示例,未传入角色或有效标识。这很有效
public async Task<EmbedToken> GetEmbedToken4(Guid workspaceId, Guid reportId, string accessLevel = "view")
{
PowerBIClient pbiClient = this.GetPowerBIClient();
var pbiReport = pbiClient.Reports.GetReportInGroup(workspaceId, reportId);
string dataSet = pbiReport.DatasetId.ToString();
// Generate token request for RDL Report
var generateTokenRequestParameters = new GenerateTokenRequest(
accessLevel: accessLevel,
datasetId: dataSet,
identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "******", roles: new List<string> { "********" }) }
);
// Generate Embed token
var embedToken = pbiClient.Reports.GenerateTokenInGroup(workspaceId, reportId, generateTokenRequestParameters);
return embedToken;
}
公共异步任务GetEmbedToken4(Guid工作空间ID、Guid报告ID、字符串accessLevel=“查看”)
{
PowerBIClient pbiClient=this.GetPowerBIClient();
var pbiReport=pbiClient.Reports.getReportingGroup(工作空间ID,reportId);
字符串dataSet=pbiReport.DatasetId.ToString();
//为RDL报告生成令牌请求
var generateTokenRequestParameters=新GenerateTokenRequest(
accessLevel:accessLevel,
datasetId:dataSet,
标识:新列表{new EffectiveIdentity(用户名:“*******”,角色:新列表{*******”}
);
//生成嵌入令牌
var embeddeToken=pbiClient.Reports.GenerateTokenInGroup(工作空间ID、报告ID、generateTokenRequestParameters);
返回令牌;
}
这是返回带有角色和有效标识的令牌的方法。这会导致错误,但没有消息或有用的反馈。好的,经过一夜的大量研究后,错误的请求响应确实隐藏了一条英文消息,该消息没有显示在浏览器中。调试器没有导致错误的部分的符号,但我在实际API响应请求时使用Fiddler代理找到了它。在我的例子中,如果您发送一个ID来启用RLS,但是服务器上的报表版本没有它,这不会忽略它,它拒绝给任何东西一个令牌。从许多帖子中可以看出,当API本身(而不是包或exa)发出实际响应时,错误请求只是一条错误消息
public async Task<EmbedToken> GetEmbedToken4(Guid workspaceId, Guid reportId, string accessLevel = "view")
{
PowerBIClient pbiClient = this.GetPowerBIClient();
var pbiReport = pbiClient.Reports.GetReportInGroup(workspaceId, reportId);
string dataSet = pbiReport.DatasetId.ToString();
// Generate token request for RDL Report
var generateTokenRequestParameters = new GenerateTokenRequest(
accessLevel: accessLevel,
datasetId: dataSet,
identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "******", roles: new List<string> { "********" }) }
);
// Generate Embed token
var embedToken = pbiClient.Reports.GenerateTokenInGroup(workspaceId, reportId, generateTokenRequestParameters);
return embedToken;
}