Forum Discussion

sddrakesh's avatar
sddrakesh
Frequent Visitor
9 years ago
Solved

https //api.powerbi.com/v1.0/myorg/datasets 403 forbidden

Can you provider detail about how to fix this issues.

I used below code to get access token and i got it successfully.

 protected void Page_Load(object sender, EventArgs e)
        {
            //Redirect uri must match the redirect_uri used when requesting Authorization code.
            string redirectUri = Properties.Settings.Default.RedirectUrl;
            string authorityUri = Properties.Settings.Default.AADAuthorityUri;
            string resourceUri = Properties.Settings.Default.PowerBiAPI;
            string clientId = Properties.Settings.Default.ClientID;
            string seceretId = Properties.Settings.Default.ClientSecretKey;
            // Get the auth code
            string code = Request.Params.GetValues(0)[0];
            TokenCache TC = new TokenCache();
            AuthenticationContext _authenticationContext = new AuthenticationContext(authorityUri, TC);
            ClientCredential cc = new ClientCredential(clientId, seceretId);
            AuthenticationResult AR = _authenticationContext.AcquireTokenAsync(resourceUri, cc).Result;
            Session["authResult"] = AR;
            //Redirect back to Default.aspx
            Response.Redirect("/Default.aspx");
        }

But when i try to get dataset with below code ,i am getting 403 forbidden error.

        protected void getDatasetsButton_Click(object sender, EventArgs e)
        {
            string responseContent = string.Empty;

            //The resource Uri to the Power BI REST API resource
            string datasetsUri = Properties.Settings.Default.PowerBiDataset;

            //Configure datasets request
            System.Net.WebRequest request = System.Net.WebRequest.Create(datasetsUri) as System.Net.HttpWebRequest;
            request.Method = "GET";
            request.ContentLength = 0;
            request.Headers.Add("Authorization", String.Format("Bearer {0}", authResult.AccessToken));

            //Get datasets response from request.GetResponse()
            using (var response = request.GetResponse() as System.Net.HttpWebResponse)
            {
                //Get reader from response stream
                using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    responseContent = reader.ReadToEnd();

                    //Deserialize JSON string
                    //JavaScriptSerializer class is in System.Web.Script.Serialization
                    JavaScriptSerializer json = new JavaScriptSerializer();
                    Datasets datasets = (Datasets)json.Deserialize(responseContent, typeof(Datasets));

                    resultsTextbox.Text = string.Empty;
                    //Get each Dataset from
                    foreach (dataset ds in datasets.value)
                    {
                        resultsTextbox.Text += String.Format("{0}\t{1}\n", ds.Id, ds.Name);
                    }
                }
            }
        }

Error Detail:'request.GetResponse()' threw an exception of type 'System.Net.WebException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2146233079
    HelpLink: null
    InnerException: null
    Message: "The remote server returned an error: (403) Forbidden."
    Response: {System.Net.HttpWebResponse}
    Source: "System"
    StackTrace: "   at System.Net.HttpWebRequest.GetResponse()"
    Status: ProtocolError
    TargetSite: {System.Net.WebResponse GetResponse()}

The Token which I got:

"Bearer eyJ0eXAiOiJKV1QiLCJhb.............TH4s-2866kDfaxnGhGU64g"

  • sddrakesh's avatar
    sddrakesh
    9 years ago

    I gave all permission to my app but isues was something different.I was trying to get token based on azure active directy app client id and app secerete key.After doing google i found that i need to pass credentials of azure login account too.

    Below code worked for me with valide token:

      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 = "............com";//your organizaion name
                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();
                    }
                }
                AccessToken Token = JsonConvert.DeserializeObject<AccessToken>(responseData);
                var result = await CallResoureApi(Token);
            }

       public async Task<string> CallResoureApi(AccessToken token)
            {
                var baseAddress = new Uri("https://api.powerbi.com/");
                string jsonresult = "";
                string requestUrl = baseAddress + "v1.0/myorg/datasets";
                var client = new RestClient(baseAddress);
                var request = new RestRequest("v1.0/myorg/datasets", Method.GET);
                request.AddHeader("authorization", "Bearer " + token.access_token);

                // execute the request
                IRestResponse response = client.Execute(request);
                var content = response.Content;
                return content;
            }

7 Replies

    • sddrakesh's avatar
      sddrakesh
      Frequent Visitor

      I gave all permission to my app but isues was something different.I was trying to get token based on azure active directy app client id and app secerete key.After doing google i found that i need to pass credentials of azure login account too.

      Below code worked for me with valide token:

        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 = "............com";//your organizaion name
                  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();
                      }
                  }
                  AccessToken Token = JsonConvert.DeserializeObject<AccessToken>(responseData);
                  var result = await CallResoureApi(Token);
              }

         public async Task<string> CallResoureApi(AccessToken token)
              {
                  var baseAddress = new Uri("https://api.powerbi.com/");
                  string jsonresult = "";
                  string requestUrl = baseAddress + "v1.0/myorg/datasets";
                  var client = new RestClient(baseAddress);
                  var request = new RestRequest("v1.0/myorg/datasets", Method.GET);
                  request.AddHeader("authorization", "Bearer " + token.access_token);

                  // execute the request
                  IRestResponse response = client.Execute(request);
                  var content = response.Content;
                  return content;
              }

      • Anonymous's avatar
        Anonymous
        Not applicable

        and for anyone like me trying to do the same but with Postman to the Power BI APIs, the same applied - you have to add valid Power BI credentials to the GET while creating an AAD token:

         

        API calls now work 🙂 

         

        Complete lack of documentation from Microsoft on this 😞  Even their 'Try It' wizard does not indicate the need for username & password ( https://docs.microsoft.com/en-us/rest/api/power-bi/groups/getgroups )

         

         

        Sam

  • Anonymous and everyone,

    Thanks for the details. Eric_Zhang ,Please confirm that it is absolutely not possible to use the PBI REST API with Client_ID and Client_Secret alone.

     

    Do I really need to pass my Windows UN and PW with the request?!?

     

    This seems:

    1. Insecure

    2. To defeat the purpose of registering an app in the first place!

      a. A major goal of creating an AppID (and corresponding Client_ID/Secret) is to prevent having to directly login to a service!

  • Got this error : when trying to work on Get token API
    {
        "error": {
            "code""",
        }
    }

    should i add something in header or body except bearer token in header  and below in body

    {
    "accessLevel""view",
    "allowSaveAs""false"
    }