Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
nunovalente
New Member

Rest API - No GUI

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!

1 ACCEPTED SOLUTION
Eric_Zhang
Employee
Employee

@nunovalente

@rossnruthie

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"];
            }


        }

View solution in original post

5 REPLIES 5
nancy1989
Regular Visitor

Check out SSIS REST API .

 

Hope it's useful for you.

 

 

Eric_Zhang
Employee
Employee

@nunovalente

@rossnruthie

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?

 

@Eric_Zhang

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!

rossnruthie
Resolver I
Resolver I

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.

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.