This post will be a quick primer on authenticating to the Power BI REST API utilizing a C# console application with SPN authentication (Application ID / Client Secret) and utilizing the MSAL library.

For anybody that has followed my previous posts this method is going to be largely similar with only minor differences in the key details. SPN authentication is preferred over Username / Password authentication as it allows the console application to truly authenticate as an application and not “as a user.” This is a much more secure and better method (though it is hasn’t always been available and some API functions don’t yet support this method, sadly). Authenticating via the MSAL library instead of the ADAL library is preferred as Microsoft has announced the termination of support for the ADAL library, so best to keep with the times.

There are two pre-requisites which must be followed before any C# application will be able to authenticate to the Power BI API:

  1. An Application must be created in Azure Active Directory. This is ultimately the “user” that we will be authenticating as and where permissions are defined. This step is the same as it was in my previous posts.
  2. Permissions must be granted within the Power BI Admin Portal to the Azure Active Directory Application granting it permission to use the Admin APIs. This is a new step specific for the ability to utilize SPN authentication.

Make sure to have the following handy from #2 above:

  • Your Azure Tenant ID
  • The Application (Client) ID from the Application you created and added to the security group
  • The Client Secret value which you set for the Application

Authentication Library

The MSAL authentication library can be found in the NuGet Package Manager in Visual Studio as the “Microsoft Identity Client.” Unlike my experience with ADAL, I’ve had no problems using the latest version which is available.

MSAL authentication library installation in NuGet

Authentication Library URIs

In the code when you make a connection to Azure Active Directory, there are a couple of things you will need to know. These are:

  • Authority URI: https://login.microsoftonline.com/<your Azure tenant id>
  • Resource URI: https://analysis.windows.net/powerbi/api
  • Redirect URI: urn:ietf:wg:oauth:2.0:oob
  • Access Scope: https://analysis.windows.net/powerbi/api/.default
  • Base URL for API queries: https://api.powerbi.com/v1.0/myorg/
  • Application (Client) ID: This is your specific Application ID from the previous section. Don’t share this.
  • Client Secret: This is your specific client secret for your application from the previous section. Don’t share this.

Authentication Process

With that pile of information in hand, you’re ready to begin. The overall process is fairly simple.

  1. An authentication request is created and sent to Azure Active Directory via MSAL. If successful, it produces a “bearer token.”
  2. That token is then placed in the header of any requests that you make to the Power BI API and functions as your credentials (until it expires and you need a new bearer token).

This small block of code performs #1:

                // Build the access scope list
                List<string> scopes = new List<string>();
                scopes.Add(PowerBIAccessScope);

                // Build the authentication request client
                var confidentialClient = ConfidentialClientApplicationBuilder
                        .Create(ApplicationID)
                        .WithClientSecret(ClientSecret)
                        .WithAuthority(new Uri(MSALAuthorityURI))
                        .WithRedirectUri(PowerBIRedirectURI)
                        .Build();

                // Request an access token with the request client and scope
                var accessTokenRequest = confidentialClient.AcquireTokenForClient(scopes);

                authResult = await accessTokenRequest.ExecuteAsync();

With that authentication result, a token is produced with the following:

                    // Create the bearer token to be used for API methods
                    authToken = authResultMSAL.Result.CreateAuthorizationHeader();

And that’s it. From here, we have a token that can be placed in all subsequent API queries.

API Queries

When authenticating with SPN, you will find that you have the best results when using entries in the Power BI “Admin API” using commands that start with “Get” and end with “AsAdmin”

I’ve found that most of these function exactly as they would as if you were logging in as a user with Admin access. If you manage to find a function which does not work with an SPN login, the error message will usually let you know this (I ran into this issue with one of the App-related functions). The good news is that Microsoft is constantly improving things behind the scenes, so that limitation will probably go away at some point.

One important item worth noting, however, is that most of the Admin API commands have read limits, such as:

Most of the time, these limits shouldn’t be a problem, but its worth knowing that they exist. Should you exceed the limit, the API will return an error message until the time limit expires.

I personally find the GetGroupsAsAdmin to be the most useful API command. This is especially useful as it supports expansion which makes getting a lot of data very efficient.

With expansion, instead of getting a list of all workspaces, then for each workspace getting a list of all reports, you can request a list of workspaces with reports expanded, so the result will be all workspaces and reports and you don’t need to request the report names separately. For large organizations, this can be hugely faster and more efficient. Many of the Admin API functions support expansion, however, I’ve only seen this feature listed on Admin API functions.

Full Sample Code

I’ve put together a very basic C# console application which, when run, will authenticate to Azure Active Directory and request a Power BI access token. It will then request a list of Workspaces (as Admin) using that token and display the first 5 to the screen.

This application is meant as a simple demo to tie everything together. It does store the authentication credentials in plaintext hardcoded in the program, so you’ll definitely want to handle that more securely in your application!

The sample application is available here.

Resources