I have an ASP.Net core 1.1 site and I want to embed BI reports on the site.
Azure Hosted Data Documentation: https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-embed-sample-app-owns-data/
Using the App Owns Data strong> sample found at https://github.com/Microsoft/PowerBI-Developer-Samples I have a working built-in report solution using the sample. However, the sample project runs on .Net Framework 4.5.2 and when I try to port the solution to my .Net kernel application, I ported the code, however the ActiveDirectorylibrary (Microsoft.IdentityModel.Clients.ActiveDirectorylibrary) in .Net Core does not contain the UserPasswordCredential method
var credential = new UserPasswordCredential(Username, Password);
The solution I found recommended on the Internet for the ASP.Net core is to use the tag helper, however now that the BI BI Embedded and Power BI services are converging with the new arrival of Power BI Premium, I don’t think I think this solution is possible due to token authentication dependency for data hosted in App Hosted.
Full Report Method:
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()
{
var credential = new UserPasswordCredential(Username, Password);
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");
using (var client = new PowerBIClient(new Uri(ApiUrl), tokenCredentials))
{
var reports = await client.Reports.GetReportsInGroupAsync(GroupId);
var report = reports.Value.FirstOrDefault();
if (report == null)
{
return View(new EmbedConfig()
{
ErrorMessage = "Group has no reports."
});
}
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."
});
}
var embedConfig = new EmbedConfig()
{
EmbedToken = tokenResponse,
EmbedUrl = report.EmbedUrl,
Id = report.Id
};
return View(embedConfig);
}
}
}
What I tried:
Adding a reference to the .Net Framework 4.6.1 in the .Net Core project to open the .NET Framework and allow the use of the .Net equivalent of IdentityModel.Clients.ActiveDirectory, but this did not seem to help.
How can I fix the problem with the library and embed it in the .Net kernel?
EDIT - answer
, @Fei Xue, HTTP--, API. 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);