March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early bird discount ends December 31.
Register NowBe one of the first to start using Fabric Databases. View on-demand sessions with database experts and the Microsoft product team to learn just how easy it is to get started. Watch now
I need to develop an API that when invoked via an endpoint will run an automatic data gathering service and add the results to a PowerBI Streaming Dataset, yet I can't seem to be able to achieve authorization.
Using .NET Core.
I've followed the tutorials to register my App with the AAD, however the ADAL Library doesn't seem to support the authentication suggested for the native app.
So far, using a web app-style registration, I'm able to get an auth token, yet when I submit a request to the API (https://api.powerbi.com/v1.0/myorg/datasets) I receive a HTTP 403 Forbidden.
This is the code I'm running to get the auth token:
var clientCredential = new ClientCredential(clientID, clientSecret); var authContext = new AuthenticationContext(authorityUri); var authResult = await authContext.AcquireTokenAsync(resourceUri, clientCredential); var token = authResult.AccessToken;
Got any Ideas? Thank you for your help!
Solved! Go to Solution.
I register a native app but generate the token not via the ADAL library. Instead I'm calling the REST API directly and the token generated could help me to refresh/retrive datasets etc.
static string getAccessTokenSilently() { string resourceUri = "https://analysis.windows.net/powerbi/api"; HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp("https://login.windows.net/common/oauth2/token"); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentLength = 0; request.ContentType = "application/x-www-form-urlencoded"; NameValueCollection parsedQueryString = HttpUtility.ParseQueryString(String.Empty); parsedQueryString.Add("client_id", clientID); parsedQueryString.Add("grant_type", "password"); parsedQueryString.Add("resource", resourceUri); parsedQueryString.Add("username", username); parsedQueryString.Add("password", password); string postdata = parsedQueryString.ToString(); //POST web request byte[] dataByteArray = System.Text.Encoding.ASCII.GetBytes(postdata); ; request.ContentLength = dataByteArray.Length; //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(dataByteArray, 0, dataByteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseJson = JsonConvert.DeserializeObject<dynamic>(responseString); return responseJson["access_token"]; } }
I register a native app but generate the token not via the ADAL library. Instead I'm calling the REST API directly and the token generated could help me to refresh/retrive datasets etc.
static string getAccessTokenSilently() { string resourceUri = "https://analysis.windows.net/powerbi/api"; HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp("https://login.windows.net/common/oauth2/token"); //POST web request to create a datasource. request.KeepAlive = true; request.Method = "POST"; request.ContentLength = 0; request.ContentType = "application/x-www-form-urlencoded"; NameValueCollection parsedQueryString = HttpUtility.ParseQueryString(String.Empty); parsedQueryString.Add("client_id", clientID); parsedQueryString.Add("grant_type", "password"); parsedQueryString.Add("resource", resourceUri); parsedQueryString.Add("username", username); parsedQueryString.Add("password", password); string postdata = parsedQueryString.ToString(); //POST web request byte[] dataByteArray = System.Text.Encoding.ASCII.GetBytes(postdata); ; request.ContentLength = dataByteArray.Length; //Write JSON byte[] into a Stream using (Stream writer = request.GetRequestStream()) { writer.Write(dataByteArray, 0, dataByteArray.Length); var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); dynamic responseJson = JsonConvert.DeserializeObject<dynamic>(responseString); return responseJson["access_token"]; } }
Dear Eric_Zhang,
When I use above code to get the token I get The remote server returned an error: (400) Bad Request.
Do you know why this error is thrown?
I just tested creating such a request and indeed I received an access token and a refresh token.
There are downsides, ADAL does token refreshment management whilst using this approach would require one to implement their own. (Or just request a new access token for each request).
Thank you for your insight, this might save a lot of people running into the same problem.
I ended up discovering another approach which I've used, and it's simpler, nonetheless I'm accepting yours as a solution as it does, indeed, solve the problem.
About the path I took: I discovered, in my PowerBI's streaming dataset settings, a unique "push url" which allows you to push data to said dataset without bothering with authorization/authentication overhead, as the link per se does the authorization part.
Once again, thank you for your really interesting code snippet!
Hey @nunovalente,
I ran into the same exact issue when setting up my embedded proof of concept. The solution that worked for me was that the user account credential needed to be made an admin of the workspace I was accessing. When I originally added the account I just made it a Member and received 403's. Once I changed it to an admin everything worked properly.
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!
Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions.
Arun Ulag shares exciting details about the Microsoft Fabric Conference 2025, which will be held in Las Vegas, NV.
User | Count |
---|---|
8 | |
3 | |
2 | |
1 | |
1 |
User | Count |
---|---|
6 | |
3 | |
2 | |
2 | |
2 |