...

Learning how to embed Power BI reports into various applications has become popular with customers as it allows for faster insights into data and reports. We will review a quick and relatively easy way to embed reports within a demo environment through this blog.

We can access the embedded Power BI reports from any one of the web applications. Embedding Power BI reports in .NET application create a different view of the reports which attract the user and offer easy access.

Learn the easy navigation of the reports as the bookmarks can be created in the embedded report. Securing the data can also be handled in embedded report.For embedding the Power BI reports, we need to set up the environment.

Environment Setup

Pre-requisites:

  • Have an Azure subscription
  • Have Power Bi Pro license account

Process to setup a Power BI report:

  • All the reports or dashboards should be placed with in the workspace in Power BI.
  • Create Power BI reports and publish it into your workspace.
  • Get the AD tenant Id
  • Register the app registration in Azure active directory.
  • Create the secret key for that app registration.
  • And give the API permissions for Power BI Service
  • After adding permissions admin has to provide admin consent for that API permissions.
  • Create the security group in Active directory and add the member as app registration to security group.
  • Power BI admin has to enable the service principal (this is only for when you are trying to embed the reports to using service principal).
  • Add the service principal (app registration) to the Power BI workspace.

Steps to embed the report:

  • We must create the .NET application and need to configure the Power BI related configurations in web.config file.
  • If you want to authenticate by using the Master user then you have to provide the username and password under master user section in config file and that user should have the access for azure and Power BI as well.
  • If you want to authenticate by using the Service principal, then you have to provide the Application secret key and azure active directory tenant id.
  • And Copy the client id from app registration and configure in the place of application Id

<appSettings>

<add key=”AuthenticationType” value=”ServicePrincipal” />

<add key=”applicationId” value=”” />

<add key=”workspaceId” value=”” />

<add key=”reportId” value=”” />

<add key=”authorityUrl” value=”https://login.microsoftonline.com/organizations/” />

<add key=”resourceUrl” value=”https://analysis.windows.net/powerbi/api” />

<add key=”scope” value=”https://analysis.windows.net/powerbi/api/.default” />

<add key=”apiUrl” value=”https://api.powerbi.com/” />

<add key=”embedUrlBase” value=”https://app.powerbi.com/” />

</appSettings>

<MasterUser>

<add key=”pbiUsername” value=”” />

<add key=”pbiPassword” value=”” />

</MasterUser>

<ServicePrincipal>

<add key=”applicationSecret” value=”” />

<add key=”tenant” value=”” />

</ServicePrincipal>

The below method is used for getting the embedded report and send to view page.

public async Task<ActionResult> EmbedReport(string username, string roles)

{

var publishername = _context.AspNetUsers.Where(x => x.UserName == User.Identity.Name).FirstOrDefault();

var report = _context.AspNetReports.Where(x => x.ReportName == roles).FirstOrDefault();

var bookmarks = _context.UserBookMarks.Where(x => x.UserId == publishername.Id && x.ReportID == report.ReportID).ToList();

//}

List<Book> bookList = new List<Book>();

foreach (var bookmar in bookmarks)

{

Book book = new Book

{

name = bookmar.BookMarkName,

displayname = bookmar.DisplayName,

state = bookmar.BookMarkState

};

bookList.Add(book);

}

Guid reportId = Guid.Empty;

Guid.TryParse(report.ReportID, out reportId);

var embedResult = await m_embedService.EmbedReport(username, roles, reportId);

if (publishername.publishername != null)

{

var data = publishername.publishername.Split(‘,’);

m_embedService.EmbedConfig.PublisherName = data.ToList();

}

m_embedService.EmbedConfig.Token = m_embedService.EmbedConfig.EmbedToken.Token;

m_embedService.EmbedConfig.Roles = roles;

m_embedService.EmbedConfig.selectedBookName = “”;

if (bookmarks != null)

{

m_embedService.EmbedConfig.bookMarks = bookList;

}

return View(m_embedService.EmbedConfig);

}

The below method is used for authentication and getting the embed url, embed token.

public async Task<bool> EmbedReport(string username, string roles, Guid reportId) {

Guid reportid = GetParamGuid(ConfigurationManager.AppSettings[“reportId”]);

var getCredentialsResult = await GetTokenCredentials();

if (!getCredentialsResult)

{

return false;

}

try

{

using (var client = new PowerBIClient(new Uri(ApiUrl), m_tokenCredentials))

{

var reports = await client.Reports.GetReportsInGroupAsync(WorkspaceId);

if (reports.Value.Count() == 0)

{

m_embedConfig.ErrorMessage = “No reports were found in the workspace”;

return false;

}

Report report;

if (ReportId == Guid.Empty)

{

m_embedConfig.ErrorMessage = “Please provide a report ID

for the selected workspace. Make sure that the report ID is valid.”;

return false;

}

else

{

report = reports.Value.FirstOrDefault(r => r.Id == reportId);

}

if (report == null)

{

m_embedConfig.ErrorMessage = “No report with the given ID

was found in the workspace. Make sure that the report ID is valid.”;

return false;

}

if (roles != “Comparative Titles”)

{

var datasets = await client

.Datasets.GetDatasetInGroupAsync(WorkspaceId, report.DatasetId);

}

GenerateTokenRequest generateTokenRequestParameters;

if (!string.IsNullOrWhiteSpace(username))

{

var rls = new EffectiveIdentity(username, new List<string>

{ report.DatasetId });

if (!string.IsNullOrWhiteSpace(roles))

{

var rolesList = new List<string>();

rolesList.AddRange(roles.Split(‘,’));

rls.Roles = rolesList;

}

generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: “view”, identities: new List<EffectiveIdentity>

{ rls });

}

else

{

generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: “view”);

}

var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(WorkspaceId, report.Id, generateTokenRequestParameters);

if (tokenResponse == null)

{

m_embedConfig.ErrorMessage = “Failed to generate embed token.”;

return false;

}

m_embedConfig.EmbedToken = tokenResponse;

m_embedConfig.EmbedUrl = report.EmbedUrl;

m_embedConfig.Id = report.Id.ToString();

}

}

catch (HttpOperationException exc)

{

m_embedConfig.ErrorMessage = string.Format(“Status: {0} ({1})\r\nResponse: {2}\r\nRequestId: {3}”, exc.Response.StatusCode, (int)exc.Response.StatusCode, exc.Response.Content, exc.Response.Headers[“RequestId”].FirstOrDefault());

return false;

}

return true;

}

private async Task<bool> GetTokenCredentials()

{

var error = GetWebConfigErrors();

if (error != null)

{

m_embedConfig.ErrorMessage = error;

return false;

}

AuthenticationResult authenticationResult = null;

try

{

authenticationResult = await DoAuthentication();

}

catch (AggregateException exc)

{

m_embedConfig.ErrorMessage = exc.InnerException.Message;

return false;

}

if (authenticationResult == null)

{

m_embedConfig.ErrorMessage = “Authentication Failed.”;

return false;

}

m_tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, “Bearer”);

return true;

}

private async Task<AuthenticationResult> DoAuthentication()

{

AuthenticationResult authenticationResult = null;

if (AuthenticationType.Equals(“MasterUser”))

{

IPublicClientApplication clientApp = PublicClientApplicationBuilder

.Create(ApplicationId)

.WithAuthority(AuthorityUrl)

.Build();

var userAccounts = await clientApp.GetAccountsAsync();

try

{

authenticationResult = await clientApp.AcquireTokenSilent(Scope, userAccounts.FirstOrDefault()).ExecuteAsync();

}

catch (MsalUiRequiredException)

{

try

{

SecureString password = new SecureString();

foreach (var key in Password)

{

password.AppendChar(key);

}

authenticationResult = await clientApp.

AcquireTokenByUsernamePassword(Scope, Username, password).

ExecuteAsync();

}

catch (MsalException)

{

throw;

}

}

}

else if (AuthenticationType.Equals(“ServicePrincipal”))

{

var tenantSpecificURL = AuthorityUrl.Replace(“organizations”, Tenant);

IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder

.Create(ApplicationId)

.WithClientSecret(ApplicationSecret)

.WithAuthority(tenantSpecificURL)

.Build();

try

{

authenticationResult = await clientApp

.AcquireTokenForClient(Scope).ExecuteAsync();

}

catch (MsalException)

{

throw;

}

}

return authenticationResult;

}

Displaying the embedded report into browser

Html code:

<div id=”embedContainer” style=”width: auto;height: calc(100vh – 75px) !important;”></div>

Java Script Code:

var models = window[‘powerbi-client’].models;

var viewMode = models.ViewMode.view;

var filtyerType = models.FilterType.BasicFilter;

var tokenType = models.TokenType.Embed;

var permissions = models.Permissions.All;

var selectedBookmark = “@Model.selectedBookName”;

var bookmarkState = “@Model.state”;

var jsArray = JSON.parse(‘@Html.Raw(Json.Encode(@Model.bookMarks))’);

var bookmarks = [];

for (var j = 0; j < jsArray.length; j++) {

bookmarks.push(jsArray[j]);

}

var config = {

type: ‘report’,

tokenType: tokenType,

accessToken: $(“#Token”).val(),

embedUrl: $(“#EmbedUrl”).val(),

id: $(“#Id”).val(),

viewMode: viewMode,

permissions: permissions,

filters: filterInfo,

//slicers: [slicer_filter],

settings: {

filterPaneEnabled: false,

//navContentPaneEnabled: true,

}

};

var embedContainer = $(‘#embedContainer’)[0];
BookmarkShowcaseState.bookmarksReport = powerbi.embed(embedContainer, config);

Conclusion

Although the process can sometimes be confusing to get started, it will make accessing reports and dashboards through other applications much more accessible than ever once established. Without login to Power BI service we can see the reports through .net use.With one Power BI subscription, we can access multiple users to see the reports by embedding the reports into the .net application.

If you need help with Power BI or just want to chat about other opportunities, please contact us.