Forum Discussion
Authorization Code Grant Flow (Power BI Embedded)
The Authorization Code Grant Flow is used to authenticate the current user but never the master user account. Therefore, the Authorization Code Grant Flow is used for first-party embedding with the user-owns-data model and never with third-party embedding and the app-owns-data model.
If yiu are using third-party embedding, you should use the User Credential Flow which is not an interactive flow. Here is a simple example.
public class PbiEmbeddedManager {
private static string aadAuthorizationEndpoint = "https://login.microsoftonline.com/common";
private static string resourceUriPowerBi = "https://analysis.windows.net/powerbi/api";
private static string applicationId = ConfigurationManager.AppSettings["application-id"];
private static string userName = ConfigurationManager.AppSettings["aad-account-name"];
private static string userPassword = ConfigurationManager.AppSettings["aad-account-password"];
private static string GetAccessToken() {
AuthenticationContext authenticationContext = new AuthenticationContext(aadAuthorizationEndpoint);
AuthenticationResult userAuthnResult =
authenticationContext.AcquireTokenAsync(
resourceUriPowerBi,
applicationId,
new UserPasswordCredential(userName, userPassword)).Result;
return userAuthnResult.AccessToken;
}
}Another key point is that you must grant permissions (i.e consent) to the Azure AD application for the master user account before you run this flow because this flow will fail if Azure AD attempts to prompt the user to consent to the application's required permissions.
I assume you are using third-party embedding and the app-owns data model and not first-party embedding with the user-owns-data model. Is this correct?
Thanks for your reply.
Yes, I plan to use third-party embedding and the app-owns data model for my project because one of the specifications is that users can view the report directly when they logged into my web application, without having a Power BI account. This is the reason I chose third-party embedding.
Another specification is that when a user logged into my web application, he/she is only allowed to view the Power BI contents that he/she has permission to, which I am not sure whether this specification can be fulfilled in third-party embedding (where one embed token for each content, consumed by any user that is able to access the page).
Is this possible in Power BI Embedded third-party scenario? Thanks in advance.
- nfadili7 years agoFrequent Visitor
My team has very similar requirements to what you've described here and we are unable to discern a scalable way of soving it. The only idea we can see might work is having multiple of these master accounts, each with different permissions and mapping our user roles to them as requests for embedded content come in. This is definitely not an ideal solution.
Have you figured out anything new regarding this problem? Does anyone on the Power BI team have a suggestion for handling this?Thanks!
- TedPattison7 years agoMicrosoft Employee
When you use third-party embedding (i.e. app-owns-data), you should use the Power BI Service API create embed tokens with an EffectiveIdentity. This makes it possible to programtically embed Power BI security roles inside the embed tokens you are generating. There is no need for multiple master accounts because a single master account can create embed tokens with varying sets of security roles embedded inside.
In a third-party embedding (i.e. app-owns-data) scenario, your application must authenticate the user and somehow track the association between your users and the roles that each users is a member of. Then when it comes time to create the embed token for a specific user, you pass the role(s) when creating an embed token with an effective identity.
Here is a code sample to give you an idea of how to get started. Note that the application determines what role(s) that the current user is a meber of and then adds those roles to the embed token. Once you have added the roles to an EffectiveIdentity, the role-based security enforement works just as it does in first-part embedding (user-owns-data) and standard Power BI SaaS scenarios
public static async Task<ReportEmbeddingData> GetReportEmbeddingDataWithRlsRoles() { string currentUserName = HttpContext.Current.User.Identity.GetUserName(); ApplicationDbContext context = new ApplicationDbContext(); var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); ApplicationUser currentUser = userManager.FindByName(currentUserName); var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context)); List<string> roles = new List<string>(); foreach (var role in currentUser.Roles) { roles.Add(roleManager.FindById(role.RoleId).Name); } string accessLevel = HttpContext.Current.User.IsInRole("Admin") ? "edit" : "view"; PowerBIClient pbiClient = GetPowerBiClient(); var report = await pbiClient.Reports.GetReportInGroupAsync(workspaceId, reportId); var embedUrl = report.EmbedUrl; var reportName = report.Name; var datasetId = report.DatasetId; GenerateTokenRequest generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: accessLevel, identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: currentUser.UserName, datasets: new List<string> { datasetId }, roles: roles) }); string embedToken = (await pbiClient.Reports.GenerateTokenInGroupAsync(workspaceId, report.Id, generateTokenRequestParameters)).Token; return new ReportEmbeddingData { reportId = reportId, reportName = reportName, embedUrl = embedUrl, accessToken = embedToken }; }- nfadili7 years agoFrequent Visitor
This is extremely helpful. Thank you for the detailed response!