Set Power BI datasource credentials using REST API, with longer-lived token - powerbi

I am able to use this REST API call to set datasource credentials in Power BI with an OAuth2 access token. e.g.,
{
"credentialDetails": {
"credentialType": "OAuth2",
"credentials": "{\"credentialData\":[{\"name\":\"accessToken\", \"value\":\"eyJ0....fwtQ\"}]}",
"encryptedConnection": "Encrypted",
"encryptionAlgorithm": "None",
"privacyLevel": "None",
"useEndUserOAuth2Credentials": "False"
}
}
When I do this, the access token is short-lived and expires in an hour. After that, Power BI can no longer connect to the datasource.
What I don't understand is why when I log in to my datasource with the Power BI service through a browser, somehow the credential doesn't seem to expire; Power BI can still refresh the data hours later.
My Question: How can I use the REST API to replicate, programmatically, what happens when I provide my datasource credentials to the Power BI Service through my browser?

When you configure connection interactively Power BI gets both an access token and a refresh token.
The API does not support doing that, but you can vote for the idea to help prioritize the feature.

Related

How to use Power BI REST API to set Databricks access key on a datasource?

I am trying to set a Databricks access key credential in a Power BI datasource through REST API calls.
I own the dataset and can set the key through the Power BI service web UI (app.powerbi.com)
But when I try to do this through REST APIs (e.g., with curl) I am getting stuck
I found my way to the datasource via the dataset:
https://api.powerbi.com/v1.0/myorg/groups/{groupId}/datasets/{datasetId}/datasources
Then I got a response back like
{
"#odata.context":"http://wabi-us-east2-c-primary-redirect.analysis.windows.net/v1.0/myorg/groups/xxx/$metadata#datasources","value":[
{
"datasourceType":"Extension","connectionDetails":{
"path":"{\"host\":\"adb-xxxx.xx.azuredatabricks.net\",\"httpPath\":\"\\/sql\\/1.0\\/warehouses\\/xxxx\"}","kind":"Databricks"
},"datasourceId":"xxxxx","gatewayId":"xxxx"
}
]
}
Using this response I tried making a call like this
PATCH https://api.powerbi.com/v1.0/myorg/gateways/xxxx/datasources/xxxx
with body:
{
"credentialDetails": "{\"credentialData\":[{\"name\":\"key\", \"value\":\"dapiXXXXX-X\"}]}",
"credentialType": "Key",
"privacyLevel": "None",
"encryptionAlgorithm": "None"
}
And I get back this error:
{"error":{"code":"UnknownError","pbi.error":{"code":"UnknownError","parameters":{},"details":[],"exceptionCulprit":1}}}%
I think I saw something about encrypting the credentials but I am unable to get the Gateway public key through the APIs (/myorg/gateways returned empty list); and anyhow this is a cloud resource, not using an on-prem gateway, and I am able to set credentials through the web UI.
What am I missing, or doing wrong?
It turned out to be oversight on my part. I forgot -H "Content-Type: application/json" on my curl command.
SMH.

How do I configure the Service Principal credentials expiration on refresh to connect Power BI Sql Azure Data Source?

I am using Powershell to update credentials on a Power BI datasource based on Sql Azure.
The credentials are that of a Service Principal's, I obtain a Sql access token and submit changes.
The payload lokos like this:
$UpdateUserCredential = #{
credentialDetails = #{
credentialType = "OAuth2"
credentials = "{`"credentialData`":[{`"name`":`"accessToken`", `"value`":`"$token`"}]}"
encryptedConnection = "Encrypted"
encryptionAlgorithm = "None"
privacyLevel = "None"
}
} | ConvertTo-Json
The datasource is set to refresh every 10 days. Do I need to update the credentials programmatically when it expires each time - how often does the credential expire?
Is there a better way to retain credentials within Power BI for a datasource connection that can survive future scheduled refreshes without having to re-enter credentials? e.g using basic username password authentication perhaps, as opposed to OAuth?
Not an expert in powerbi, but for the service principal, you could create a secret i.e. credential whose lifetime is as long as possible with powershell New-AzureADApplicationPasswordCredential, make sure you have installed the AzureAD powershell module first. (In the portal, at most you can set it with 3 years)
Connect-AzureAD
New-AzureADApplicationPasswordCredential -ObjectId <app-registration-object-id> -EndDate ((Get-Date).AddYears(100))

PowerBI - Power Query Fetch credentials from Azure Vault

We have a requirement to fetch data from a rest api into powerbi and schedule a refresh every night. The rest api support jwt authentication so it needs header with xapikey and access token.
I have managed to write a function in power query to get access token from our auth endpoint and able to inject access token for the rest api call and it works fine with powerbi-desktop. I have published the report to powerbi cloud.
The auth endpoint require username and password, we would not like to store this details in .pbix file and publish to cloud but instead use azure key vault and powerbi to fetch details at runtime.
Please advise ?
Power Automate has a great Azure Vault connector.
You could make a simple 3-action flow:
A post to that URL will json back the secret/credentials.
Now, here is the goofy part - hide that URL in a permissioned location (Onedrive, Sharepoint, etc). Have your pbi pickup from that location, using privileged credentials. Now the URL and the credentials get picked up at runtime, and neither is persisted in PBIX.
I am assuming that there is an available premium PAutomate env in which to spin up that flow, of course. But, given that you already have an azure vault, that seems like a standard PBI+ toolkit to have at that point.

Power BI - scheduled refresh - OData source - anonymous

I have an issue with the scheduled refresh function in Power BI. I have published a PBIX file to the web environment of Power BI. As with other PBIX files, I set the scheduled refresh via the on-premises gateway. My PBIX file has data from several sources (MySQL, OData, other Web connectors). 
Setting up and connecting the MySQL source to scheduled refresh (via the gateway) works fine. However, when trying to connect the OData source to the gateway, this fails. The message shows that credentials are invalid, "AccessUnauthorized". However, via PBI Desktop there is no need for me to use credentials (as access is via Anonymous, with an API key "Bearer ........."). 
The following settings are used (in the gateway setup tab): 
Type of source:  OData
URL: https://tcodata.azurewebsites.net/estimates
Authentication method: Anonymous
Privacy-settings: None
The following code is used in PBI Desktop:
let
apiUrl = "https://tcodata.azurewebsites.net/estimates",
Source = OData.Feed(apiUrl , null, [Implementation="2.0", Headers = #"Authorization"=Text.From(ApiKey)]])
in
Source
The API key refers to ApiKey = Bearer ........(key here)
No real authentication is needed, because it is accessed as Anonymous. However, when setting the scheduled refresh, this does not work (as credentials are said to be invalid).
Help is much appreciated, thanks!
The question was answered on the PowerBI forum:
When refreshing odata source in Power BI service, with the power query code as yours, you don't need to add it under the on-premise gateway, just go to "data setting"->"schedule refresh"->edit credential for that odata source, select "anonymous".
Source

Power BI Authentication using REST API without GUI using Java (Refresh Token)

Currently I am getting Power BI Report from Power BI services with access token and embedding this report into IFrame using Azure AIDL Authentication.
Using this Java Library I am getting an JWT access token and fetching into my Power Bi report.
Below are the problems with this approach:
1) Access token has a short validity of 60 mins. and after that I fetch new access token using refresh token.
2) But the refresh token itself has a validity of 14 days and after that I need to manually log in and update the refresh token manually.
I want to avoid manual log in and wondering if there is any way to make this automatic.
Any suggestions would be appreciated.