Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!

Reply
Anonymous
Not applicable

Authorization Code Grant Flow (Power BI Embedded)

Authorization Code Flow diagram

I found this diagram with the corresponding explanation here which I am not sure whether my understanding of the flow is correct. Here is my understanding about the diagram above and would be appreciated if someone could correct me if I am wrong.

 

  1. The client application redirects the User Agent (The "master account" with Power BI Pro License and with Azure Global Admin Role in third-party embedding scenario) to the Azure AD authorization endpoint and lets the User Agent authenticates via Azure username and password.
  2. The Azure AD authorization endpoint redirects the user agent back to the client application with an authorization code.
  3. The client application requests an access token from the Azure AD token issuance endpoint by providing the authorization code.
  4. The Azure AD token issuance endpoint returns an access token and a refresh token.
  5. The client application uses the access token to authenticate and call to the Web API INCLUDING obtain an embed token for third-party embedding.
  6. After authenticating the client application, the web API returns the requested data.

 

Along the process, three different type of tokens were received. Each of their purposes is stated below:

  • Authorization code: Used for verification with Azure AD token issuance endpoint to obtain an access token
  • Access token: Used to call Power BI Web API
  • Refresh token: Used to request additional access tokens
  • Embed token: Used along with embed URL and embed report ID for embedding in custom web application. (Embed Token, Embed report ID and Embed URL are the 3 items required to do 3rd party embedding)

Thanks in advance for the help. 

14 REPLIES 14
TedPattison
Employee
Employee

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?

Anonymous
Not applicable

Hi Ted! Thanks for your detailed response with code examples. Something I think would be useful and would allow anyone to implement this flow in any language would be an example REST API call with the payload outlined and possibly where to acquire each component of that payload.

I've been searching for a week off and on and it's extremely frustrating for something so simple as getting a bearer token to make requests to be so obscure or only represented in Java/C# or other lower-level languages where you utilize a library from Microsoft. Often times with no reference on where to obtain those libraries, how to use them, where this code should run... etc

Is there any documentation on that specifically? Or would you be so kind as to give us this example?

Signed,
    a very frustrated developer who has set up this exact situation using other services and has never had this much trouble.

Anonymous
Not applicable

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.

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!

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
  };


}

 

This is extremely helpful. Thank you for the detailed response!

Hi All,

 

I have my website using different Identity provider not the AAD.

 

When I embed using the App-own-data model , how the authentication of the user happen??

 

Do i have to do Identity provider federation enabled between the existing IDP and Azure ad to authenticate the user to use the power BI embedded report?

 

 

When you use App-Owns-Data model, your web application is responsible for authenticating the user. You can use Azure AD when you authenticate the user, but it is not required as you can use another Identity provider that you want. If you use a seperate identity provide, there is not need to invovle Azure AD at all in the user authentication process.

 

The part where Azure AD is involved is when you obtain an app-only token to make calls in the Power BI Service API under the identity of the application as opposed to the identity of the user.

 

I hope this helps.  

Thanks for the answer TedPattison..

This really helps .. Irrespective of the users , the PowerBI embedded reports will be displayed based on the embed token authorization .. There is no need that the users should be added to AAD..

In this case , If I have to restrict user access to a report and As well as RLS , how can I use it if I don’t use AAD ?

With the app-own-data model, Azure AD know nothing about the users. When your application authenticates users, it must somehow track which uers have greater or lessor levels of access. All of the design and implementation of this is part of your application design. You might have roles where some users are Admins and other are not. Then you app can show a link to open an admin report for admin users when not lighting up that link for non-admin users.

 

Yes, you can use RLS when using app-owns-data. The trick is that you have to embed one or more roles inside the embed token using the EffectiveIdentiy class that is in the Power BI Service API. Of course, your application needs extra code and lookup tables to determine which roles to add to the embed token for each specific user.

 

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
};


}

Thanks for the great info ..Is there any documentation for this ??
I would like to use that as my reference and implement it in my application ..

I am sorry but the Microsoft documentation and sample apps are really bad and need some serious love.

Anonymous
Not applicable

Hi @TedPattison ,

I'm new to Power BI Embedded.

My web application is written in JET using IDM tokens. How should I be able to validate users form JET application to Power BI API?

Oh fine..I will try some digging ..Thanks for the info ..

Helpful resources

Announcements
April AMA free

Microsoft Fabric AMA Livestream

Join us Tuesday, April 09, 9:00 – 10:00 AM PST for a live, expert-led Q&A session on all things Microsoft Fabric!

March Fabric Community Update

Fabric Community Update - March 2024

Find out what's new and trending in the Fabric Community.