'PowerBI - getting EmbedToken - Unauthorized

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 docs.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



Solution 1:[1]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kavyasaraboju-MT