cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
seijim
Microsoft
Microsoft

How to use Power BI Rest API without GUI authentication (redirect uri)

I'm developing an Azure worker role application which pushes data to PowerBI.com service.

I referred a C# sample client application via Git Hub. But it authenticates using GUI (redirect uri) during the below step.

>> token = authContext.AcquireToken(resourceUri, clientID, new Uri(redirectUri)).AccessToken.ToString();

 

I need a sample code without GUI (redirect uri) authentication which means silent mode authentication.

 

Thanks,

-Seiji

1 ACCEPTED SOLUTION
jocaplan-MSFT
Microsoft
Microsoft

You can use the user name and password flow that AAD supports. This 3rd party client library has an example: https://github.com/Vtek/PowerBI.Api.Client

View solution in original post

53 REPLIES 53
Jchandran
New Member

Can we use POWERBI API without Azure AD. I have a reporting server
skaratela
Frequent Visitor

Hi all,

 

with regards to the original subject, silent authenntication and also embedding PowerBI, i want to mention how i managed to get this to work and hopefully may help someone.

 

The way i managed to get silent authentication to work for embedding report items into a custom application was to use a master powerBI account (created via Office 365) and then setup a Native App in Azure Active Directory (AAD) and make the master account be the owner of the Native App and set the correct permissions in the app and generate a Key.

 

you then need to make a POST request to https://login.microsoftonline.com/common/oauth2/token with the following Keys and Values:

 

KEYVALUE
grant_typepassword
scopeopenid
resourcehttps://analysis.windows.net/powerbi/api
client_id<the App ID for the Native App created in AAD>
client_secret<the Key generated from the Native App created in AAD>
username<Master PowerBI Account e.g. abc.master@onmicrosoft.com>
password<Password for the Master PowerBI account>

 

You can test out your POST request by using the software application 'Postman'.

 

This will return back a the access token.

 

You then use the access token to pull back a Dashboard, Report or Tile - but bearing in mind that in PowerBI the Report / Dashboard must be bundelled into a PowerBI APP and owned by the Master Account - otherwise this won't work.

 

<html>
<script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/jquery/dist/jquery.js"></script>
<script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/powerbi-client/dist/powerbi.js"></script>
<script type="text/javascript">
window.onload = function () {
var embedConfiguration = {
    type: 'dashboard', //  dashboard
	//change report embed url to dashboard embed url
    accessToken: 'TOKEN GENERATED FROM POST REQUEST GOES HERE',
    embedUrl: 'https://app.powerbi.com/dashboardEmbed?dashboardId=YOUR DASHBOARD ID - You can find this out by using http://docs.powerbi.apiary.io/ '  
	}; 
var $reportContainer = $('#dashboardContainer');
var report = powerbi.embed($reportContainer.get(0), embedConfiguration);
}

function reloadreport(){
	var element = $('#dashboardContainer');
	alert(element);
	var report = powerbi.get(element);
	report.reload().catch(error => {console.log(error)  });
};
</script> 
<div id="dashboardContainer"></div>
</html>  

 

Hope this helps someone.

 

Shaheen K

Followed exactly the same steps but i am getting following error
{
"error": "invalid_grant",
"error_description": "AADSTS70002: Error validating credentials. AADSTS50126: Invalid username or password\r\nTrace ID: b089ee76-8a60-4a83-b353-fa015f0b3e00\r\nCorrelation ID: d7878fb5-5ce6-4eed-9644-a92b1a6c2069\r\nTimestamp: 2018-03-22 17:56:27Z",
"error_codes": [
70002,
50126
],
"timestamp": "2018-03-22 17:56:27Z",
"trace_id": "b089ee76-8a60-4a83-b353-fa015f0b3e00",
"correlation_id": "d7878fb5-5ce6-4eed-9644-a92b1a6c2069"
}

 

i have my application registered as web apllication since native app didn't have option for client_secret.
Note: i am doing this for federated user.

 

Another observation: i have another application which is registered as native client, if i create a console app to generate token it works but same code does not work in case if its a website.

Please help, have been haning on this for almost last 3 days.

Anonymous
Not applicable

After digging and digging, found this article which allows for federated users.

 

https://blogs.msdn.microsoft.com/azuredev/2018/01/22/accessing-the-power-bi-apis-in-a-federated-azur...

Anonymous
Not applicable

I've also encountered this with a federated account. Triple checks that the credentials are correct.

 

As a work around, I've found that creating a user inside AAD allows the credentials to be validated.

 

 

Thanks,

Lyon Till

Anonymous
Not applicable

I've also encountered this with a federated user. If I create a user in AAD itself, the credentials validate successfully.

Thank you @skaratela for the most concise write-up yet on how to actually get access to the Power BI API. However I am still banging my head on the wall trying to simply get my groups listed in Postman. I have tried many iterations, including following your process exactly. In all cases I am getting a 403 Forbidden on API calls, even though I have can authenticate and get an access token.

 

I have tried a Web App in AAD using a client_secret and grant_type=client_credentials; I have tried a Native App using grant_type=password (because AAD Native apps no longer give you a client_secret to work with). I have my master account as the owner of both AAD apps, and full Power BI API permissions granted to them.

 

My most recent authorization call/response looks like this, using an AAD Native App owned by my master account as the Client:

 

POST to https://login.windows.net/{{tenantId}}/oauth2/token

{
"grant_type":"password" "client_id":"xxxxxxxxxx" "resource":"https://analysis.windows.net/powerbi/api" "username":"xxxxxx@xxxxx.xxx" "password":"xxxxxxxxxxx" "scope":"openid"
}

RESPONSE:

{
    "token_type": "Bearer",
    "scope": "Capacity.Read.All Capacity.ReadWrite.All Content.Create Dashboard.Read.All Dashboard.ReadWrite.All Data.Alter_Any Dataset.Read.All Dataset.ReadWrite.All Group.Read Group.Read.All Metadata.View_Any Report.Read.All Report.ReadWrite.All Tenant.Read.All Workspace.Read.All Workspace.ReadWrite.All",
    "expires_in": "3599",
    "ext_expires_in": "0",
    "expires_on": "1520882770",
    "not_before": "1520878870",
    "resource": "https://analysis.windows.net/powerbi/api",
    "access_token": "...",
    "refresh_token": "...",
    "id_token": "..."
}

Then I take that access_token, and use it to try and get my groups:

 

GET https://api.powerbi.com/v1.0/myorg/groups
Authorization: Bearer {{access_token}}

And I get a 403 error. Same result when I make the initial token request using an AAD Web App and providing client_id and client_secret parameters. Again, both my AAD apps have full Power BI API permissions granted, and are owned by my master account.

 

I have spent many hours struggling with this. Any help would be greatly appreciated.

Hi @rogersmj

 

So it sounds like there is some permission problem and your request is being rejected - but you are getting the token back fine which is great!

 

Just one thing to note:

 

You mention 'I have my master account as the owner of both AAD apps, and full Power BI API permissions granted to them.' which makes me think perhaps you haven't bundelled your dashboard in a PowerBI App (and I don't mean a AAD app in this instance). Get your dashboard and put it in a PowerBI App and make that PowerBI App owner the same master account that you used for the AAD Apps. This is done through the PowerBI web portal (you should see 'Apps' on the left navigation pane.

 

Have you done this? - Let me know how you get on.

 

Shaheen

 

Works for me

Hi @sk I'm also getting the following error:

 

{
"error": "invalid_grant",
"error_description": "AADSTS65001: The user or administrator has not consented to use the application with ID '3cc9615b-ed4c-436b-82a5-fb701c7e240d' named 'Launch BI'. Send an interactive authorization request for this user and resource.\r\nTrace ID: 46533754-26e3-43d9-9bea-2206d7ab3100\r\nCorrelation ID: c9e76852-19f3-4173-9866-5f914509fb7b\r\nTimestamp: 2018-01-16 17:31:30Z",
"error_codes": [
65001
],
"timestamp": "2018-01-16 17:31:30Z",
"trace_id": "46533754-26e3-43d9-9bea-2206d7ab3100",
"correlation_id": "c9e76852-19f3-4173-9866-5f914509fb7b"
}

 

I believe I have followed your instructions, with the exception that I have created a WebApp as opposed to a Native app

I just found the problem, the grant type needs to be "client_credentials" not "password"

Hi @skaratela,

I tried this https://login.microsoftonline.com/common/oauth2/token with param in post method but getting below error-

 

"error": "invalid_grant",
"error_description": "AADSTS65001: The user or administrator has not consented to use the application with ID 'xxxxxxxxxxxxxxxxxxxx' named 'LSNTestAPP'. Send an interactive authorization request for this user and resource.\r\nTrace ID: ac36a442-1603-479b-aad5-b8c75b0f4300\r\nCorrelation ID: 4cd0780a-2184-46ab-8d91-8a83987c5e72\r\nTimestamp: 2017-12-22 06:14:36Z",

Hi @dharamgoyal it seems like perhaps the permissions in the Native Application in Azure haven't been set correctly. Also, are you using the same account for both the Native Application and also that same account when you are making the post request?

Finally, have you bundelled your dashboard into a power BI application and made the owner of that app the same account as above?

I know, it's so confusing.

Cheers
skaratela
Frequent Visitor

Has anyone managed to do a silent auth using angular 4? 

ChrisWilliams
Helper II
Helper II

This is a very useful discussion, especially regarding the apps that my company develops, which are typically Windows services running on some headless datacenter server that doesn't usually have user interaction or a gui.  

 

Consider a simple example: you have a service running that collects performance monitor stats from one or more servers and you want to ship those off via direct push to Power BI.  You might have a UI available when you installed the app, but it's not something that you'll be able to or want to return to in order to update a token.

 

Many of the approaches mentioned below are good, but are now outdated:

 

  • AcquireTokenByRefreshToken() that @aevers describes is no longer implemented in ADAL 3.
  • The user name/password AAD flow that @jocaplan-MSFT mentions is no longer supported in ADAL3 (UserCredential class doesn't contain passwords any longer), although you can still access it by using ADAL 2.   However username/password can be problematic, because we've seen that AAD may require additional authenication steps (2FA, or smart cards in the case of Microsoft, etc.) which is I'm sure why MSFT dropped it from ADAL3.

I may be missing some alternative approaches, so if there's a better way to handle authentication, please let me know.  I'm new to Power BI  :).

 

In the ideal case, a Power BI app would require user authentication/acceptance to the rights requested at install time.  And from that point on, it would not require any additional user interaction via a GUI.  Users could terminate access by removing the application from their accepted application list.

 

In the case of AAD applications, it functions pretty much like this.  Our app requires admin-level approval to add them to the organizational application list, but from that point on we can access AAD without further prompting.  If this was applied to Power BI, I'm sure there would be some additional work/thinking required because:

  • Just because an app was added to an organization doesn't imply that that app should have access to all Power BI workspaces.  Perhaps a workspace needs a token that can be supplied to external applications to use in an http request.
  • Sometimes having to request an admin to add an application to an organization can be troublesome, especially if the application is really only for one user's workspace. Ideally a user could allow access for a single user's application without admin interaction.

So my ask in this message is to help me clear up my understanding on what is possible and the recommended approach for apps like mine today.  Also, want to raise this issue again now that the technology has evolved to see what if anything is on the roadmap.

How did you go with this ? 

Were you able to find a way to silentyly authenticate a user of the PowerBi service ?

 

What was your solution to avoiding a mandatory GUI login ?

Shaun,

 

There are a couple steps needed to silently authenticate.

 

1. You need to manually log in with the account once because PowerBI will prompt you with permissions. Once you've accepted, the account can be set up for silent authentication.

 

2. In c#, aquire the token like this

// Create an instance of TokenCache to cache the access token
TokenCache TC = new TokenCache();

// Create an instance of AuthenticationContext to acquire an Azure access token
authContext = new AuthenticationContext(authority, TC);

string resourceUri = "https://analysis.windows.net/powerbi/api";
string clientID = "your client id here";
string email = "your email here";
string password = "your password here";

// Call AcquireToken to get an Azure token from Azure Active Directory token issuance endpoint
token = authContext.AcquireToken(resourceUri, clientID, email, password).AccessToken;

 

If you perform these steps properly, you can do whatever you want in the background. I have this in an executable file that's triggered by my database any time there is new data that I want to push out to a PBI dataset.

 

I have largely followed the following post in our integration.

https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-get-azuread-access-token/

 

Do the steps you detail above to achieve silent Powerbi login also apply if our architecture falls into the 

Access token for Power BI users (user owns data) 

category from the article link I posted ?

 

Ours is an an application written and distrubuted to our clients who all have their own Powerbi pro accounts and content.

We are just wanting a way they can consume their content within our application and not have to log in each and every time.

 

Big thanks in advance for your previous post and any response

If that's the case I think you'll probably need them to login every time. The access token expires so you'll need their password each time even if you want to silently authenticate.

 

If we were storing their username and password in our application then can we pass it silently each time to log them in silently rather than having them be redirected to a website to have them login each and every time ?

 

I just see no point in the API in this particular instance especially for non web based interfaces.

 

Here is an API that you can invoke to consume Powerbi content

BUT

everytime you wish to consume it we need to redirect you to a website to login and then then come back to the non webbased interface to consume it

 

The user experience is better if you have a link to the Report URL inside an iframe because at least after you log in there you have the remember me option that doesnt prompt you again for a long period of time.

 

But use the API and we are forced to have them jump from a non web ui, into a web ui and then back to the non web ui.

 

 

Helpful resources

Announcements
UG GA Amplification 768x460.png

Launching new user group features

Learn how to create your own user groups today!

Power BI October Update 2021.jpg

Power BI Release

Click here to read more about the October 2021 Release!

Community Connections 768x460.jpg

Community & How To Videos

Check out the new Power Platform Community Connections gallery!

Teds Dev Camp Oct. 2021 768x460.jpg

Power BI Dev Camp - October 28th, 2021

Mark your calendars and join us for our next Power BI Dev Camp!

Top Solution Authors
Top Kudoed Authors