嵌入嵌入式Power BI会产生406不可接受的错误

时间:2019-02-27 09:00:30

标签: .net asp.net-core powerbi powerbi-embedded

当我们尝试在现有应用程序中嵌入“嵌入式Power BI”时,我们遇到了406不可接受的错误。 为了确保这不是由我们自己的应用程序引起的,我们在power bi示例存储库中使用了示例代码:https://github.com/Microsoft/PowerBI-Developer-Samples。我们使用“应用拥有的数据”方案,因为我们的最终用户不拥有Power BI Pro许可证。我们遵循了所有必要的配置步骤,并在web.config中提供了必要的凭据/标识。

第一次尝试运行该应用程序时,出现连接关闭错误。经过研究,我们发现这是由错误的TLS版本引起的。将ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;添加到控制器即可解决此问题。

我们遇到的下一个错误是在以下代码行中:

var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ApplicationId, credential);

此行以http异常结束:406-不可接受。当我们使用Fiddler检查流量时,此错误被认为是合乎逻辑的,因为我们的Azure AD将我们的ADFS服务器称为具有JSON内容的accept标头的依赖方,而我们的ADFS返回了xml正文。 我们的结论是,AcquireTokenAsync无法在我们公司的Azure Azure AD / ADFS环境中正常工作。为了对此进行调查,我们进行了一些测试:

  1. 我们尝试使用MSAL库而不是使用标准ADAL库。但是,这导致了相同的错误。

  2. 使用以下代码向Azure AD发送(原始)发布请求以获取身份验证令牌:

    try
    {
        client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
        _result = await client.PostAsync(
            new Uri("https://login.windows.net/common/oauth2/token"), new FormUrlEncodedContent(
                new[]
                {
                new KeyValuePair("resource", "https://analysis.windows.net/powerbi/api"),
                new KeyValuePair("client_id", ClientId),
                new KeyValuePair("grant_type", "password"),
                new KeyValuePair("username", UserName),
                new KeyValuePair("password", Password),
                new KeyValuePair("scope", "openid"),
                }));
    }
    catch (HttpOperationException ex)
    {
        //Bad Request
        var content = ex.Response.Content;
        Console.WriteLine(content);
    }

这导致了以下错误,我们无法解决:

{“错误”:“ invalid_grant”,“错误描述”:“ AADSTS70002:验证凭据时出错。AADSTS50126:无效的用户名或密码\ r \ n跟踪ID:b8a97eae-63a4-4d56-8afd-e18eb7b02800 \ r \ n相关ID: 3e168d8f-61ab-4b7f-b9c4-6ae7870c5e06 \ r \ nTimestamp:2018-12-03 12:59:38Z“,” error_codes“:[70002,50126],” timestamp“:” 2018-12-03 12:59: 38Z“,” trace_id“:” b8a97eae-63a4-4d56-8afd-e18eb7b02800“,” correlation_id“:” 3e168d8f-61ab-4b7f-b9c4-6ae7870c5e06“}

  1. 我们成功使用以下代码执行了交互式登录:

    var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ApplicationId, new Uri("http://localhost:42734/"), new PlatformParameters(PromptBehavior.Auto));

但是,这并不理想,因为我们不希望最终用户每次使用嵌入在应用程序中的Power BI时(交互式)使用AD中的代理帐户登录:)

  1. 按照Microsoft的博客中有关此情况的操作也未产生任何结果: https://blogs.msdn.microsoft.com/azuredev/2018/01/22/accessing-the-power-bi-apis-in-a-federated-azure-ad-setup/

问题是如何解决此问题。...请参见我们经过数月(!)搜索后找到的答案。

1 个答案:

答案 0 :(得分:0)

经过几个月的搜索,我在世界另一端的一位同事帮助了我。解决方案很简单:使用在Azure AD中创建但在依赖AD中未知的代理帐户。这样,身份验证将在Azure AD中进行,并且不使用依赖的ADFS。这样可以避免我们遇到的所有错误,并启用ADAL和MSAL身份验证。

当我们开始将Power BI嵌入我们自己的.NET Core应用程序时,我们发现发布请求是当前的最佳选择,因为我们无法在.NET Core库中找到用于用户名/密码身份验证的适当方法。发帖请求也可以使用前面提到的解决方案。

我希望这个提示可以节省我们花费的时间...