Forum Discussion

eprochasson's avatar
eprochasson
Frequent Visitor
8 years ago
Solved

401 when accessing any Power BI API endpoints

Hi,

 

I'm trying to access Power BI API in the goal to ultimately embed dashboards for my customers.

 

I manage to generate an access token (which I assume valid: if I put wrong credentials, it fails to generate the token). I created a Power BI App using the wizard at https://dev.powerbi.com/apps. However, whatever I do, I get a 401 http error when talking to the API. Typically, the endpoint https://api.powerbi.com/v1.0/myorg/groups doesn't require any parameter. I set the header as indicated, using the access token.

 

FWIW, I'm using the Python ADAL library to generate the access token (using application certificate -- the values given by the wizard at https://dev.powerbi.com/apps), then the requests library for simple http connection; my point being: I don't think it's a programming error, here's the code.

 

def get_access_token(self):
context = adal.AuthenticationContext(
self.authority_url + '/' + self.tenant,
validate_authority=True,
api_version=None)
token = context.acquire_token_with_client_credentials(self.resource, self.application_id, self.application_key)
return token['accessToken']

def make_headers(self):
return {
'Content-Type': 'application/json; charset=utf-8',
'Authorization': "Bearer {}".format(self.get_access_token())
}

def get_groups(self):
endpoint = "https://api.powerbi.com/v1.0/myorg/groups"
headers = self.make_headers()
return requests.get(endpoint, headers=headers)

 

Calling `get_groups` returns a 401 http error.

 

 

The generated header looks something like:

 

 

Authorization: Bearer eyJ...pBQ

which seems fine to me.

 

 

- The App in the AD tenant has the right permission (generated by the wizard).

- I use https://login.windows.net for the "authority url", but that doesn't seem to be a problem anyway since the access token is generated properly

 

I followed the tutorial here https://docs.microsoft.com/en-us/power-bi/developer/embedding-content and tried pretty much everything I could Google to solve my problem, with no luck.

 

Thanks!

 

Edit: the error is for any endpoints I tried, not only "groups".

I also tried with command line curl:

curl -v -X POST -H 'Authorization: Bearer eyJ...zA' "https://api.powerbi.com/v1.0/myorg/groups" -H 'Content-Length: 0'

and get:

< HTTP/1.1 401 Unauthorized
< Cache-Control: no-store, must-revalidate, no-cache
< Transfer-Encoding: chunked
< Content-Type: application/octet-stream
< Server: Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< X-Frame-Options: deny
< X-Content-Type-Options: nosniff
< RequestId: 7f8535e6-10ff-422b-8f81-a5cabb8b930b
< Date: Wed, 10 Jan 2018 09:05:20 GMT

as a response (so it doesn't seem to be a problem with my code). Note that if I put an wrong token (e.g.: if I remove some characters) I get a 403 error instead, which definitely makes me think this is not a problem with how I forge the query.

 

Additional Edit: the permission for the App in AD, I granted everything to be sure (I also try only granting what's required, and tried various combination):

 

 

 

They are saved and granted. I also double-checked that the credentials I use to generate the access token correspond to this app.

  • eprochasson's avatar
    eprochasson
    8 years ago

    I found something that work and documented it (with code) here: https://bitbucket.org/omnistream/powerbi-api-example

     

    Hopefully it would help other people in need!

     

    It's not entirely satisfying: I'm notably not too sure why I should use this authentication endpoint instead of the one I found in other documentation, nor why I have to use a username/password on top of the app credentials, especially since it's not a super secure way to do it; I'm concerned it may get deprecated in the future. But it works.

3 Replies

  • v-ljerr-msft's avatar
    v-ljerr-msft
    Microsoft Employee

    Hi eprochasson,

     

    What App Type did you choose when you register your application with the Power BI App Registration Tool? The App type selection will depend on the type of application you are using. So you may need to choose Native app in your scenario.

    • Use Server-side Web app for web apps or web APIs.
    • Use Native app for apps that run on client devices. You will also choose *Native app if you are embedding content for your customers regardless of what the actual application is. Even for web applications.***

    As I'm not familiar with Python ADAL library and the command line you're using, could you try using Postman like below with a new created access token(either with your code or Postman) to see if the Get Group api works, in order to narrow down this issue? :smileyhappy:

     

     

    Regards

    • eprochasson's avatar
      eprochasson
      Frequent Visitor

      Thanks for your help!

       

      I used Web App. Native app doesn't allow to get a secret key for the app (apparently). I must admit the line you quote (that I read before) is quite confusing. Note that I tried with Native App before, with no success either.

       

      I replicated (and included) the examples using Curl, which is similar to Postman.

       

      I may have found a workaround using REST only, I'll confirm and post a solution here when it's ready. It appears the authentication method is wrong, it works if I use both application credentials AND user credentials, and negotiate the access token with 

      https://login.microsoftonline.com/common/oauth2/token

      instead of 

      https://login.microsoftonline.com/<tenant id>/oauth2/token

       as indicated in the documentation.

       

      None of that is properly documented so I can't explain why, it just seems to work. It works using a "Web App", and default permissions.

      • eprochasson's avatar
        eprochasson
        Frequent Visitor

        I found something that work and documented it (with code) here: https://bitbucket.org/omnistream/powerbi-api-example

         

        Hopefully it would help other people in need!

         

        It's not entirely satisfying: I'm notably not too sure why I should use this authentication endpoint instead of the one I found in other documentation, nor why I have to use a username/password on top of the app credentials, especially since it's not a super secure way to do it; I'm concerned it may get deprecated in the future. But it works.