Azure托管数据文档:https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-embed-sample-app-owns-data/ 使用在https://github.com/Microsoft/PowerBI-Developer-Samples找到的App Owns Data示例,我已经成功地使用该示例嵌入了报告解决方案。然而,示例项目运行在.Net Framework 4.5.2上,当尝试将解决方案迁移到我的.Net Core应用程序时,我已经迁移了代码,但是在.Net Core中的ActiveDirectorylibrary(Microsoft.IdentityModel.Clients.ActiveDirectorylibrary)不包含UserPasswordCredential方法。
var credential = new UserPasswordCredential(Username, Password);
我发现在线推荐的ASP.Net Core解决方案是使用标签助手,然而现在随着Power BI Embedded和Power BI服务与新的Power BI Premium的融合,我认为由于对应用主机数据的令牌身份验证的依赖关系,这种解决方案可能不再可行。
完整的报告控制器方法:
public class ReportController : Controller
{
private static readonly string Username = ConfigurationManager.AppSettings["pbiUsername"];
private static readonly string Password = ConfigurationManager.AppSettings["pbiPassword"];
private static readonly string AuthorityUrl = ConfigurationManager.AppSettings["authorityUrl"];
private static readonly string ResourceUrl = ConfigurationManager.AppSettings["resourceUrl"];
private static readonly string ClientId = ConfigurationManager.AppSettings["clientId"];
private static readonly string ApiUrl = ConfigurationManager.AppSettings["apiUrl"];
private static readonly string GroupId = ConfigurationManager.AppSettings["groupId"];
public async Task<ActionResult> EmbedReport()
{
// Create a user password cradentials.
var credential = new UserPasswordCredential(Username, Password);
// Authenticate using created credentials
var authenticationContext = new AuthenticationContext(AuthorityUrl);
var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ClientId, credential);
if (authenticationResult == null)
{
return View(new EmbedConfig()
{
ErrorMessage = "Authentication Failed."
});
}
var tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, "Bearer");
// Create a Power BI Client object. It will be used to call Power BI APIs.
using (var client = new PowerBIClient(new Uri(ApiUrl), tokenCredentials))
{
// Get a list of reports.
var reports = await client.Reports.GetReportsInGroupAsync(GroupId);
// Get the first report in the group.
var report = reports.Value.FirstOrDefault();
if (report == null)
{
return View(new EmbedConfig()
{
ErrorMessage = "Group has no reports."
});
}
// Generate Embed Token.
var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(GroupId, report.Id, generateTokenRequestParameters);
if (tokenResponse == null)
{
return View(new EmbedConfig()
{
ErrorMessage = "Failed to generate embed token."
});
}
// Generate Embed Configuration.
var embedConfig = new EmbedConfig()
{
EmbedToken = tokenResponse,
EmbedUrl = report.EmbedUrl,
Id = report.Id
};
return View(embedConfig);
}
}
}
我尝试过的方法:
在.Net Core项目中添加.Net Framework 4.6.1的引用,以公开.Net Framework并允许使用IdentityModel.Clients.ActiveDirectory的.Net等效版本,但似乎没有帮助。
我该如何解决库问题并嵌入到.Net Core中?
修改 - 答案
基于@Fei Xue提供的答案,我编写了一个HTTP辅助类,执行对API的post。根据返回的JSON创建对象并使用现有的身份验证令牌。
辅助类:
#region Settings
public static string BaseUrl
{
get
{
return "https://login.microsoftonline.com/common/oauth2/token";
}
}
#endregion
public static async Task<HttpResponseMessage> MakeAsyncRequest(string url, Dictionary<string, string> content)
{
var httpClient = new HttpClient
{
Timeout = new TimeSpan(0, 5, 0),
BaseAddress = new Uri(url)
};
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type: application/x-www-form-urlencoded", "application/json");
if (content == null)
{
content = new Dictionary<string, string>();
}
var encodedContent = new FormUrlEncodedContent(content);
var result = await httpClient.PostAsync(httpClient.BaseAddress, encodedContent);
return result;
}
对象:
public class AAD
{
public string token_type { get; set; }
public string scope { get; set; }
public string expires_in { get; set; }
public string ext_expires_in { get; set; }
public string expires_on { get; set; }
public string not_before { get; set; }
public string resource { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
}
控制器调用:
var url = APIHelper.BaseUrl;
var content = new Dictionary<string, string>();
content["grant_type"] = "password";
content["resource"] = "https://analysis.windows.net/powerbi/api";
content["username"] = "<username>";
content["password"] = "<password>";
content["client_id"] = "<clientid>";
var response = await APIHelper.MakeAsyncRequest(url, content);
var result = response.Content.ReadAsStringAsync().Result;
var AAD = JsonConvert.DeserializeObject<AAD>(result);