Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!
We are using the PowerBI API to deploy reports to the PowerBI Service (not embedded). Currently we have written a command line tool that takes a few parameters and performs the import. However, we are not able to use this on our build server or as a service because it requires interactive authentication. We have tried registering and using both native and web apps in the developer portal, but both approaches require and integrated login (pop up) somewhere up the chain. Ideally I would like to run the command line tool with an API Key and Secret, not associated with any user and perform the operations required.
There appear to be a couple of work arounds:
In short, I'd just like to know if I am missing a trick in setting up headless authentication for the API with an API Key and Secret, is it at all possible? (I always end up with a 403 Forbidden using the web app keys generated on the developer portal).
I've had the same issue recently and have had to switch to using a device code. I've just dumped a copy of my code below.
There are a few steps required.
1 - Run it initially to get a device code. You will have to go to a verification url and enter a code. This then authenticates the app.
2 - Serialise the token cache from the authentication token.
Next time through, create a token cache from the saved state and you can log back in.
It all feels a bit hacky, but appears to work ok. I'm planning on creating a simple github project with all of this in, but am still debugging some issues at the moment
public PowerBIClient(string clientId, string key, HttpClient httpClient, ILogger log, byte[] state) { Log = log; ClientId = clientId; _key = key; _httpClient = httpClient; var tokenCache = state == null ? new TokenCache() : new TokenCache(state); _authenticationContext = new AuthenticationContext(AuthorityUri, tokenCache); }
#pragma warning disable RCS1163 // Unused parameter. private async Task<string> GetAccessTokenAsync(CancellationToken ct) #pragma warning restore RCS1163 // Unused parameter. { if (_accessToken == null) { if (_authenticationContext.TokenCache.Count > 0) { try { var result = await _authenticationContext.AcquireTokenSilentAsync(ResourceUri, ClientId).ConfigureAwait(false); _accessToken = result.AccessToken; Log.Debug("Got cached access token until {expire} ({duration})", result.ExpiresOn, result.ExpiresOn - DateTimeOffset.UtcNow); return _accessToken; } catch (Exception ex) { Log.Warning("Failed to acquire token from cached {exception}", ex.Message); } } } if (_accessToken == null) { var codeResult = await _authenticationContext.AcquireDeviceCodeAsync(ResourceUri, ClientId).ConfigureAwait(false); Log.Warning("Need authentication from {location} {code}", codeResult.VerificationUrl, codeResult.UserCode); var result = await _authenticationContext.AcquireTokenByDeviceCodeAsync(codeResult).ConfigureAwait(false); Log.Debug("Got new access token until {expire} ({duration})", result.ExpiresOn, result.ExpiresOn - DateTimeOffset.UtcNow); _accessToken = result.AccessToken; } else { var result = await _authenticationContext.AcquireTokenSilentAsync(ResourceUri, ClientId).ConfigureAwait(false); Log.Debug("Got refreshed access token until {expire} ({duration})", result.ExpiresOn, result.ExpiresOn - DateTimeOffset.UtcNow); _accessToken = result.AccessToken; } return _accessToken; }
Hi @njrandell
Are you able to supply some more detail? I probably need some more info to get these functions working.
Cheers,
Phil
Have a look at https://github.com/sceneskope/powerbi
Admitedly the documentation isn't great, but I've had this working for the last few months and am happy to make it clearer if needed.
I got my authentication running headless with passing a UserCredential instance to the AuthContext. Therefor I provide username and password. See also: https://github.com/Microsoft/PowerBI-Developer-Samples/blob/master/App%20Owns%20Data/PowerBIEmbedded...
They are using a UserPasswordCredential object, I am not aware of the differences of those two classes. But both should work headless.
I'm using .Net core, and last time I checked those libraries don't support username and passwords. In fact I remember seeing a comment on github from one of the developers saying they won't add in username and passwords.
I'm using the libraries I created on github to push into power bi from a number of places, such as a raspberry pi running a dotnet core app, all the way through to a service fabric service running .net 452.
If you aren't using .Net core, then you are ok with the UserPasswordCredential object.
User | Count |
---|---|
15 | |
2 | |
1 | |
1 | |
1 |
User | Count |
---|---|
18 | |
11 | |
5 | |
4 | |
3 |