0

I have been trying WITH NO LUCK, to get an embed token to be able to embed my powerbi reports into my existing .netcore web api application. The front end looks like a super easy 1 simple react component that power bi has prepared for me.

But for the backend, I'm literally going in circles.

I got to the point where I decided the cleanest way for me to do this would be through an HTTP Trigger function.
(see this: https://www.taygan.co/blog/2018/05/14/embedded-analytics-with-power-bi )

As an important side note: I DID already grant my application the necessary delegate READ permissions to the power bi Apis)

Another side note, is that I am attempting to do the master user, app owns data approach

Another side note, is that you will see that my link above, the code shows you to get an AAD auth token using a method that is no longer supported (seemingly) by microsoft, so I changed that line of code as you'll see below

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.PowerBI.Api;
using Microsoft.PowerBI.Api.Models;
using Microsoft.Rest;
using Newtonsoft.Json;

namespace PowerBiExample
{
    public class EmbedContent
    {
        public string EmbedToken { get; set; }
        public string EmbedUrl { get; set; }
        public string ReportId { get; set; }
    }
    
    public static class Test
    {
        private static string tenantId = "this is the id of my entire organization";
         static string authorityUrl = $"https://login.microsoftonline.com/{tenantId}";
         static string resourceUrl = "https://analysis.windows.net/powerbi/api";
        static string apiUrl = "https://api.powerbi.com/";
        private static string clientId = "this is the client id of my application that i gave delegate permissions to"; 
        private static string clientSecret = "this is the secret of the application i gave delegate permissions to";
        private static string username = "ad master user that i WANTED to sign into power bi with";
        private static string password = "that ad users pw"; 
        private static Guid groupId = Guid.Parse("workspaceid in powerbi"); 
        private static Guid reportId = Guid.Parse("report id from within that workspace"); 
        
        
        [FunctionName("Test")]
        public static async Task<IActionResult> RunAsync(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
        {

            var credential = new ClientCredential(clientId, clientSecret);
            var authenticationContext = new AuthenticationContext(authorityUrl);
            // var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, clientId, credential);
            var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, credential);
            string accessToken = authenticationResult.AccessToken;
            var tokenCredentials = new TokenCredentials(accessToken, "Bearer");
    
            using (var client = new PowerBIClient(new Uri(apiUrl), tokenCredentials))
            {
                // Embed URL
                Report report = client.Reports.GetReportInGroup(groupId, reportId);
                string embedUrl = report.EmbedUrl;

                // Embed Token
                var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
                EmbedToken embedToken = client.Reports.GenerateTokenInGroup(groupId, reportId, generateTokenRequestParameters);

                // JSON Response
                EmbedContent data = new EmbedContent();
                data.EmbedToken = embedToken.Token;
                data.EmbedUrl = embedUrl;
                data.ReportId = reportId.ToString();
                var s = JsonConvert.SerializeObject(data);
                return new JsonResult(s);
                // JavaScriptSerializer js = new JavaScriptSerializer();
                // string jsonp = "callback(" +  js.Serialize(data) + ");";
                //
                // // Return Response
                // return new HttpResponseMessage(HttpStatusCode.OK) 
                // {
                //     Content = new StringContent(jsonp, Encoding.UTF8, "application/json")
                // };
            }
        }
    }
}

I DO get the Authorization Token returned. I DO NOT get the Embed Token returned. I get unauthorized for that.

Also important note: 1. I also didn't enable Service Principal like it says to do here learn.microsoft.com/en-us/power-bi/enterprise/… (my IT dept said I can't). and 2. they are not an admin or member on the workspace but when I try to add them as member, they are not available. It's an Application, not a user or a group. What should I do

Lizi
  • 93
  • 16
  • `masteruser` is a very bad idea... – jazb May 12 '22 at 02:01
  • so pls help me. what should i do and why is master user a very bad idea? – Lizi May 12 '22 at 02:16
  • Check the rights of your app to the workspace in which you are trying to generate the embed token - it must be `Member` or `Admin`. https://learn.microsoft.com/en-us/power-bi/developer/embedded/embed-service-principal#step-4---add-the-service-principal-to-your-workspace – Andrey Nikolov May 12 '22 at 05:35
  • @AndreyNikolov. I tried checking that but 2 problems with it. 1. I also didn't enable Service Principal like it says to do here https://learn.microsoft.com/en-us/power-bi/enterprise/service-premium-service-principal (my IT dept said I can't). and 2. they are not an admin or member on the workspace but when I try to add them as member, they are not available. It's an Application, not a user or a group. What should I do – Lizi May 12 '22 at 11:24
  • please!!!!!!!!!!!! – Lizi May 12 '22 at 18:13

1 Answers1

3

Please check if below points can give an idea to work around.

  1. A fiddler trace may be required to investigate further. The required permission scope may be missing for the registered application within Azure AD. Verify the required scope is present within the app registration for Azure AD within the Azure portal ex: openid , profile, offline etc depending on the requirement and the user logged in.

When using a master user, you'll need to define your app's delegated permissions ( known as scopes). The master user or Power BI admin is required to grant consent for using these permissions using the Power BI REST APIs.

  1. For master users, it is essential to grant permissions from the Azure portal.
  2. Also check if the group Id provided is correct,
  3. Also For Analysis Services, the master user has to be a gateway admin.

enter image description here

  • Your web app uses a user account to authenticate against Azure AD and get the Azure AD token. The master user needs to have a Power BI Pro or a Premium Per User (PPU) license.
  • After successful authentication against Azure AD, your web app will generate an embed token to allow its users to access specific Power BI content.
  • Please go through this considerations to generate embed token carefully and give proper permissions.

Note: For security reasons, the lifetime of the embed token is set to the remaining lifetime of the Azure AD token used to call the GenerateToken API.

Therefore, if you use the same Azure AD token to generate several embed tokens, the lifetime of the generated embed tokens will be shorter with each call. Sometimes that can be the reason for the unauthorized error due to expiry of embed token

And also check if you need to provide datasetId

Some references:

  1. Unauthorized response on GetReportInGroupAsync PowerBI Embedded API call using Service Principal - Stack Overflow
  2. Register an app to embed Power BI content in a Power BI embedded analytics application - Power BI | Microsoft Docs
  3. Understand the permission tokens needed for embedding a Power BI application - Power BI | Microsoft Docs
kavyaS
  • 8,026
  • 1
  • 7
  • 19
  • thanks for this!!!! But I think part of the issue is I couldn't get the login to work (the aad part) with master user credentials, so if you look at my code, I login using APPLICATIONS CLIENT ID AND CLIENT SECRET. when searching into this, I saw that it's common practice to login using application id and secret when api is calling another api (like here my api is calling power bi api) – Lizi May 17 '22 at 13:38
  • also, why does it need access to read graph api? – Lizi May 17 '22 at 17:46
  • user.read api permission for graph to read user profile is present in the portal even before adding the api permissions for powerbi. We can add or remove required permissions. – kavyaS May 18 '22 at 04:52