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

Grow your Fabric skills and prepare for the DP-600 certification exam by completing the latest Microsoft Fabric challenge.

Reply
aromero
Regular Visitor

C# Power BI API 401 Unauthorized ServicePrincipalIsNotAllowedByTenantAdminSwitch

I already have done all this steps:

  1. I have my Tenant account properly setup, I have done all these steps. Done
  2. Allow Service Principal to use the API Services. Done
  3. Add Tenant account to the Security groups with all privilages to read and write. Done
  4. Add the Account to the Workspace as an Admin. Done
  5. Use the latest Pbi SDK v3. and use the latest Code samples. .Net Framework 4.8.  Done.

 

I sucessfully got a Token, but when I try to get the report (client.Reports.GenerateTokenInGroupAsync) I got the next error:

 

 

HTTP/1.1 401 Unauthorized
Content-Length: 0
X-PowerBI-Error-Info: ServicePrincipalIsNotAllowedByTenantAdminSwitch
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: deny
X-Content-Type-Options: nosniff
Access-Control-Expose-Headers: RequestId,X-PowerBI-Error-Info
request-redirected: true

 

 

 

This is my function to get the Token:

 

 

private async Task<AuthenticationResult> DoAuthentication()
{
    AuthenticationResult authenticationResult = null;
    var AuthenticationType = _pbiSettings.AuthenticationType;
    var Tenant = _pbiSettings.TenantId;
    var ApplicationId = _pbiSettings.ApplicationId;
    var ClientId = _pbiSettings.ClientId;
    var ApplicationSecret = _pbiSettings.ClientSecret;
    string[] Scope = _pbiSettings.Scope.Split(';');
    var tenantSpecificURL = _pbiSettings.AuthorityUrl.Replace("organizations", Tenant);
    IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder
                                                                    .Create(ClientId)
                                                                    .WithClientSecret(ApplicationSecret)
                                                                    .WithAuthority(tenantSpecificURL)
                                                                    .Build();
    try
    {
        authenticationResult = await clientApp.AcquireTokenForClient(Scope).ExecuteAsync();
    }
    catch (MsalException) { throw; }
    catch (Exception){ throw; }
    return authenticationResult;
}

 

 

 

This the code trying to get the report:

 

 

using (var client = new PowerBIClient(new Uri(_pbiSettings.ApiUrl), tokenCredentials))
{
    GenerateTokenRequest generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
    Report report=null;
    try
    {
        report = await client.Reports.GetReportInGroupAsync(new Guid(workspaceId), new Guid(reportId));
    }
    catch (Exception)
    {
        throw;
    }
    
    //Generate the Embed Token
    var TokenResponse =
        await client.Reports.GenerateTokenInGroupAsync(new Guid(workspaceId), report.Id, generateTokenRequestParameters);
    if (TokenResponse == null)
    {
        pbiEmbedReport.ErrorMsg = "Failed to generating embed Token";
        return pbiEmbedReport;
    }
    //Form the Result
    pbiEmbedReport.EmbedToken = TokenResponse;
    pbiEmbedReport.EmbedUrl = report.EmbedUrl;
    pbiEmbedReport.Id = report.Id.ToString();
    return pbiEmbedReport;
}

 

 

 

***If I use the HttpClient Request, I sucessfully get the token and the report. I noted, that in the Post HttpClient Request I'm able to indicate Grant_type="password"

vs when I use the sdk, I noted that automaticaly set the grant_type to "client_credentials". and I get a 401 Error. not sure if that could be the problem.

 

 

 

What else could be failing ?  as far as I know I'm following all the documentation.

I also read all these posts:

https://community.powerbi.com/t5/Developer/Power-BI-API-return-401-Unauthorized-response/m-p/1084320...

https://community.powerbi.com/t5/Developer/Embedding-Service-principle-AppOwnsData-401/m-p/699010

https://community.powerbi.com/t5/Service/Custom-Connector-Unauthorized-401-Power-BI/m-p/819016#M8071...

 

 

2 REPLIES 2
aromero
Regular Visitor

Ok I solved this, my problem was with the RSL. (Roles)

My dataset, it was configure with a Dynamic Role, and I didn't know it. actually  just few Users were on that Role. so I was getting that error because that.

 

I was using on this line of code, which only works when your dataset is not Identity required.

GenerateTokenRequest generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");

 

How do I resolve it?

1.- Make sure your Dataset is or not Identity Required(Using RLS).  Use the next two lines to evaluate:

if (dataset.IsEffectiveIdentityRequired == true){
//"This report is Identity Required. Make sure to Provide a Valid Username."
}
if (dataset.IsEffectiveIdentityRolesRequired == true) {
//Do your validations
//"This report is Identity Roles Required. Make sure to Provide a Valid Role(s)."
}

 

If is Identity Required, then you will need the Username(email) and the Roles,  as far as I know Dynamic is the default Role, but the PowerBI Report developer should know this information. So do the next on code:

 var rls = new EffectiveIdentity(Username, new List<string> { dataset.Id });
                if (!string.IsNullOrWhiteSpace(Roles))
                {
                    var rolesList = new List<string>();
                    rolesList.AddRange(Roles.Split(','));
                    rls.Roles = rolesList;
                }
                var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view", identities: new List<EffectiveIdentity> { rls });

 

Send  the  GenerateTokenRequestParameters variable to the function to get the EmbedToken,

as next:

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

 

You should be good to go with those actions.

jesusmoreno
Regular Visitor

Hello,

It looks like the error you are getting is due to the service principal not having access to the Power BI Service. 

You can find how to enable that option in Step 3  of the Microsoft Documentation. 

Please note that you need to enable "Allow service principals to use Power BI APIs". 

Also, it is highly recommended that the service principal that was created be added to a security group and then added within Step 3.

 

Lastly, you will have to add the service principal to the workspace, not your personal workspace, that you would like for it to have access to. It need to be either a member or admin of that workspace. 

Helpful resources

Announcements
RTI Forums Carousel3

New forum boards available in Real-Time Intelligence.

Ask questions in Eventhouse and KQL, Eventstream, and Reflex.

MayPowerBICarousel1

Power BI Monthly Update - May 2024

Check out the May 2024 Power BI update to learn about new features.