Get certified in Microsoft Fabric—for free! For a limited time, the Microsoft Fabric Community team will be offering free DP-600 exam vouchers. Prepare now
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
Solved! Go to Solution.
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
Technically speaking, you could store their usernames/passwords and achieve the silent authentication that you desire. But I would strongly discourage doing that. Storing passwords is almost never a good idea.
You should look around and see if there is any way to grab the logged in user's windows credentials, and pass that to the acquireToken method instead of the username and password strings. I would imagine that there is a simple way to do that.
Thanks for your reply.
That is the difficulty we are having - As it doesnt appear that the acquireToken method has user name and password parameters. So whether we get their windows login, or whether the login to our application was the same as their Powerbi account, its how do we pass the username and password in the acquireToken method we are stuck on.
Do you have a link to an example where the acquireToken method has username and password elements for a "user owns data" scenario ?
There are a number of articles online about silent authentication for "Access token for non-Power BI users (app owns data)"
I havent been able to find any about silent auhtentication for "Access token for Power BI users (user owns data)"
Reference https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-get-azuread-access-token/
This article has an example.... This example is for when your users will manually log into Azure AD with their organziation login. This is used when embedding content for Power BI users that will access content they have access to within the Power BI service.
But like I explain above I want to log them in silently as whether we store the username and password or obtain it from another source we will have it. As our application is non web UI, it makes it a ordinary user exeprience opening a web page for a user to log in with credentials we will already have access to, before having to run our application. We would like to do it for them in the background using the API.
If you have any links for additional details on how we would achieve what you have said is technically possible that would be fantastic. Thanks in advance for the time taken to read and address my query
The code snippet I sent in a previous reply to you shows how to call the acquire token method with an email and password....
We must be missing something as your snippet uses authContext.AcquireToken
The AcquireToken() doesn’t accept the email and password parameters at least not from the following link
Hi have found a way using SSIS that should work from anywhere. I will write a blog on the www.radacad.com site and post here the details.
Hey Phil! Sorry for reviving this old post 😅 but can you send me the link of your article? I haven't found it in the site
Thanks in advance
@ChrisWilliams I came here to post this exact thing. I can't find a simple way to "silent" authenticate because of these issues. Is there a standard approach for this now? Do we need to submit a feature request?
Below is the code for getting AccessToken by giving User credential, client Id (without AccessCode & Azure-Login UI).
using Newtonsoft.Json;
using System.IO;
using System.Text;
private async void SetAccessToken()
{
List<KeyValuePair<string, string>> vals = new List<KeyValuePair<string, string>>();
vals.Add(new KeyValuePair<string, string>("grant_type", "password"));
vals.Add(new KeyValuePair<string, string>("scope", "openid"));
vals.Add(new KeyValuePair<string, string>("resource", "https://analysis.windows.net/powerbi/api"));
vals.Add(new KeyValuePair<string, string>("client_id", ""));
vals.Add(new KeyValuePair<string, string>("client_secret", ""));
vals.Add(new KeyValuePair<string, string>("username", ""));
vals.Add(new KeyValuePair<string, string>("password", ""));
string TenantId = "";
string url = string.Format("https://login.windows.net/{0}/oauth2/token", TenantId);
HttpClient hc = new HttpClient();
HttpContent content = new FormUrlEncodedContent(vals);
HttpResponseMessage hrm = hc.PostAsync(url, content).Result;
string responseData = "";
if (hrm.IsSuccessStatusCode)
{
Stream data = await hrm.Content.ReadAsStreamAsync();
using (StreamReader reader = new StreamReader(data, Encoding.UTF8))
{
responseData = reader.ReadToEnd();
}
}
Token = JsonConvert.DeserializeObject<AccessToken>(responseData);
}
public class AccessToken
{
public string token_type;
public string scope { get; set; }
public string expires_in { get; set; }
public string expires_on { get; set; }
public string not_before { get; set; }
public string resource { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
public string id_token { get; set; }
}
Hi @vijaybkodare I have tried this using Postman and I'm 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 just found the problem, the grant type needs to be "client_credentials" not "password"
I just realised that using the "client_credentials" grant type may not be suitable as the username and password parameters are not used. I switched back to using the "password" grant type but I also had to login to my Azure AD -> Registered Apps -> <App Name> -> All Settings -> Required Permissions and then click the "Grant Permissions" button
Hi @skaratela it's odd because I didn't actually make any changes, I just clicked the "Grant Permissions" button. I think it's another bug
That's very useful. However, when registering the application, what values did you use for the redirect URL? It appears to be a mandatory field but in this case, it is not being used
After executing the above code by replacing the values for ClientID,ClientSecret and TenantId, I am seeing the below error :
Message: The remote server returned an error: (400) Bad Request.
Status: ProtocolError.
I have also tried using the authority uri as https://login.microsoftonline.com/<TenantID>/oauth2/token but still the same error.
I really appreciate your response why I am seeing this bad request error.
Can you please clarify what is the TenantId in the above code represents?
https://login.windows.net/common/oauth2
its actually "common" in my code. By ethier it can be domain according to azure active directory. Both works. I work as above.
Hi there,
I'm using the same flow as you mentioned here but I'm always getting error at that part.
If I use client credentials such as client_id then I get one token without any user consent dialog . (As long as I develop native java application I cant open a browser to pop it up.) Unfortunately I cant use this token to make a rest api call because I always get 403 forbidden. I understand that authentication for rest api calls should be user specific for Power Bi. So I use this example same as in the adal4f implementation and also with the post man rest tool. I encounter same error in both as you see in the pictures.
{ "error": "invalid_grant", "error_description": "AADSTS65001: The user or administrator has not consented to use the application with ID 'ef193d6d-5585-4286-bc7f-31eadd94446c'. Send an interactive authorization request for this user and resource.\r\nTrace ID: bd8c1e80-4965-4d85-b607-700505157055\r\nCorrelation ID: 9189059d-abea-4f30-8de1-321f25010dbd\r\nTimestamp: 2016-10-26 09:10:34Z", "error_codes": [ 65001 ], "timestamp": "2016-10-26 09:10:34Z", "trace_id": "bd8c1e80-4965-4d85-b607-700505157055", "correlation_id": "9189059d-abea-4f30-8de1-321f25010dbd" }
private static void getPasswordCredentinal() throws IOException { HttpPost signIn = new HttpPost("https://login.windows.net/{mytenant}/oauth2/token"); List<NameValuePair> nvps = new ArrayList<>(); nvps.add(new BasicNameValuePair("grant_type","password")); nvps.add(new BasicNameValuePair("client_id","myId")); nvps.add(new BasicNameValuePair("resource","https://analysis.windows.net/powerbi/api")); nvps.add(new BasicNameValuePair("username","myuser")); nvps.add(new BasicNameValuePair("password","mypass")); nvps.add(new BasicNameValuePair("scope","openid")); //optinal signIn.setEntity(new UrlEncodedFormEntity(nvps)); CloseableHttpClient client = HttpClients.custom().build(); HttpResponse response = client.execute(signIn); System.out.println(response.getStatusLine().toString()+" "+response.getStatusLine().getReasonPhrase()+" "+response.getStatusLine().toString()); String s = EntityUtils.toString(response.getEntity()); JSONObject jsonObject=new JSONObject(s); accessToken = (String) jsonObject.opt("access_token"); System.out.println(" json object >"+jsonObject); }
Both produce the same result.
"error_description": "AADSTS65001: The user or administrator has not consented to use the application with ID 'ef193d6d-5585-4286-bc7f-31eadd94446c'. Send an interactive authorization request for this user and resource
So is there anyting I'm missing? Or is there any way to bypass this consent process programmatically?
Thanks for your help
Hi there,
What do you use for the Username/Password for your solution.
We use SSO at our company so not sure what account I can use.
I currently use my personal credentials. We're planning a change soon. What sucks is that PowerBI doesn't really allow multiple users to build reports off an API dataset. Our plan is to get a shared Service Account, pay for a license for the service account, and keep the password private to our group.
Check out the October 2024 Power BI update to learn about new features.
Learn from experts, get hands-on experience, and win awesome prizes.
User | Count |
---|---|
21 | |
6 | |
3 | |
3 | |
3 |