cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Highlighted
Kudo Commander
Kudo Commander

Issue with getting data via API with bearer token

Hi,

 

I am using an API that requires a bearer token embedded in the header that has a 30 min lifespan. I have constructed a Power Query ("M") that will pass the username and password to a Microsoft OWIN oauth token endpoint and this returns the required token correctly.

 

let
 url = #"Token URL",
 GetJson = Web.Contents(url,
     [
         Headers = [#"Accept"="application/json",
                    #"Content-Type"="application/x-www-form-urlencoded;charset=UTF-8"],
         Content = Text.ToBinary("username=XXXXXXX&password=XXXXXXXX&grant_type=password") 
     ]
 ),
 FormatAsJson = Json.Document(GetJson),

// Gets token from the Json response
 AccessToken = FormatAsJson[access_token],
 AccessTokenHeader = "bearer " & AccessToken,
 GetJsonQuery = Web.Contents(#"Search URL",
     [
         Headers = [#"Authorization"=AccessTokenHeader]
     ]
 ),
FormatAsJsonQuery = Json.Document(GetJsonQuery)
in
    #"FormatAsJsonQuery"

 

I then try to pass that token through to a Web.Contents function to process the API query with the authorisation token to pull the required data into Power BI.

 

On running this I get a prompt saying "Access to the resource is forbidden. Edit Credentials". So I try setting the credentials to anonymous but it keeps returning "Access is forbidden". This is probably due to the requirement of the "Authorization" key to pass the token. My assumption is Power BI then tries to intercept this and provide the authorisation prompt but this will not work for my requirement.

 

 

I know the token that is returned is working for authentication as I can use it externally from Power BI to run a GET query effectively, I just can't make this function inside Power BI.

 

Is there something I'm missing? Researching this proves fairly light on details and contradictory answers for this use case so if someone could clarify any experience it would be appreciated.

 

Thanks.

12 REPLIES 12
Highlighted
Community Support
Community Support

Re: Issue with getting data via API with bearer token

Hi @aexley,

 

I think your formula based on below article, right?

Get Data from Twitter API with Power Query

 

Web.Contents method not support directly add username and password to content query.

 

Usually logic of request:

1.  Call login API to get the access token.

2.  Use access token call other operation api.

 

Sample:

 

    WebResponse = Web.Contents(WebServiceURI,
        [Content = Text.ToBinary(WebServiceContent),
         Headers = [Authorization="Bearer " & AccessToken,
                    #"Content-Type"="application/json",
                    Accept="application/json"],
         Timeout = WebTimeout])

 

In addition, API can allow "username", "password", "token" as the parameters to query string, but they must be defined in design.

 

For example:

 

RequestUri= BasUri?UserName:xxxxx&Passowrd:xxxxxx&Token:xxxxx

 

I'd recommend you take a look at the Official documentation and find out the correct way to call api.

 

Regards,

Xiaoxin Sheng

Community Support Team _ Xiaoxin
If this post helps, please consider Accept it as the solution to help the other members find it more quickly.
Highlighted
Kudo Commander
Kudo Commander

Re: Issue with getting data via API with bearer token

Thank you Xiaoxin Sheng ( @v-shex-msft ),

 

The logic you have provided is what I am trying to perform as the token has a 30 min lifespan and I can't get users of the report to manually enter a token each time.

 

To call a token I have to send a POST request with the username, password and grant_type embedded as content. The API does not accept a URI with parameters to return a token.

 

This works to return my token:

GetJson = Web.Contents(url,
     [
         Headers = [#"Accept"="application/json",
                    #"Content-Type"="application/x-www-form-urlencoded;charset=UTF-8"],
         Content = Text.ToBinary("username=uXXXXXX&password=pXXXXXX&grant_type=password") 
     ]
 ),
 FormatAsJson = Json.Document(GetJson),

// Gets token from the Json response
 AccessToken = FormatAsJson[access_token],
 AccessTokenHeader = "bearer " & AccessToken

 This will give me a variable (AccessTokenHeader) with the access token. If there is another way to do this please let me know.

 

 

Highlighted
Community Support
Community Support

Re: Issue with getting data via API with bearer token

Hi @aexley,

 

Can you share some detail content of the api which you want to invoke?

 

>>The logic you have provided is what I am trying to perform as the token has a 30 min lifespan and I can't get users of the report to manually enter a token each time.

 

You can write a custom function to get token which your account, then invoke this method before operation other api.

 

Regards,

Xiaoxin sheng

Community Support Team _ Xiaoxin
If this post helps, please consider Accept it as the solution to help the other members find it more quickly.
Highlighted
Kudo Commander
Kudo Commander

Re: Issue with getting data via API with bearer token

Hi @v-shex-msft,
 
Thanks for following this through. The instructions provided for the API are as follows:
 
1. Create an OAuth2 Session
Create a session and get a token (that you need to pass in your Web API request) using your user credentials by doing a “HTTP POST“ request on the URL. 

 

The base URL used for all operations is formatted as follows: https://{deployedAPIServer}/api/{resource}

 
The “https://{deployedAPIServer}/token/" Microsoft OWIN oauth token endpoint with parameters:
 
 "username", with value: the user login
 "password", with value: the user password
 "grant_type" : password (Resource Owner Password Credentials)
 
The content-type of the request should be: application/x-www-form-url encoded
 

Link to image of C# snippet provided in instructions


If the credentials are valid, the response would be a JSON object:
{"access_token":"..base64 encoded string","token_type":"bearer","expires_in":seconds}"
 
2. Call a Secure API
Call a secure rest API with token.
Set the returned token in your request header as a "Bearer" authentication and make the post, get, delete, .. HTTP call.

 

Link to image of C# snippet provided in instructions

 

Does this help?

Community Support
Community Support

Re: Issue with getting data via API with bearer token

Hi @aexley,

 

Sorry for slow response.

I haven't found a way to use power query invoke the sign in credentials, perhaps you can refer to below steps:

 

1. Package the sample code to a webservice.

   Sample : (just for reference)

 

 Public string GetToke(string UserName, string Password,string deployedAPIServer)
{
	string token="";
using (HttpClient client= new HttpClient())
{
	Client.DefaultRequestHeaders.Add("Accept","application/json");
	FormUrlEncodedConten credentialsContent =new FormUrlEncodedConten(new Dictionary<string,string> {{ "username",UserName},{"password",Password},{"scope","read"},{"grant_type","password"}};
	Task<HttpResponseMesage> requestTask= client.PostAsync("https://{"+deployedAPIServer+"}/api/token",credentialsContent);
	string jwt= requestTask.Result.Conten.ReadAsStringAsync().Result;
	token= (string)jObject["access_token"];
};
return token;
}


2. At query editor side, use web.content to invoke above service and store the access token.

 

 

Sample:

let
    username="xxxx",
    passowrd="xxxxx",
    apiurl="xxx.xxx.xxx",
    AccessToken= Web.Contents(WebServiceURL& "?GetToke("+username+&","&+passowrd+&","&+apiurl+&")")
in
    AccessToken


3. Use token to operation other functions.

 

 

Some useful links:

Understanding the Username-Password OAuth Authentication Flow

 

Regards,

Xiaoxin sheng

Community Support Team _ Xiaoxin
If this post helps, please consider Accept it as the solution to help the other members find it more quickly.
Highlighted
Advocate I
Advocate I

Re: Issue with getting data via API with bearer token

Hi aexley,

 

Have you tried with Bearer (in capital letters)? I spent hours with that and finally that was the stupid problem.
Now, my big problem is that this solution does not work me on the Power BI service.

 

Good luck!

Highlighted
New Member

Re: Issue with getting data via API with bearer token

Hi 

i had the same issue but with some tweaking i was able to get the post and get token together and work.

 

my issue was i needed token registeration and use the token as bearer token to get the api call

 

--------------------

hope this helps for some one.

 

------------------

let
url = "http://###########/Portal/api/v1/Token",
url1 = "http://#########/Portal/api/v1/myapi?FromDate=2017/09/29 01:00:00&ToDate=2017/09/29 23:00:00&",

GetJson = Web.Contents(url,
[
Headers = [#"Accept"="application/json",
#"Content-Type"="application/x-www-form-urlencoded;charset=UTF-8"],
Content = Text.ToBinary("grant_type=password&username=###########&password=###########&client_id=###########&client_Secret=###########")
]
),

FormatAsJson = Json.Document(GetJson),
AccessToken = FormatAsJson[access_token],
AccessTokenHeader = "bearer " & AccessToken,

GetJson1 = Json.Document(Web.Contents(url1 , [Headers=[Authorization= AccessTokenHeader ]]))


in

GetJson1

Highlighted
New Member

Re: Issue with getting data via API with bearer token

Hi

i had the same issue which i was able to figure it with some tweak.

Like a post  request with a get with bearer token to get the data

 

hope this helps

 

let
url = "http://###########/Portal/api/v1/Token",
url1 = "http://#########/Portal/api/v1/myapi?FromDate=2017/09/29 01:00:00&ToDate=2017/09/29 23:00:00&",

GetJson = Web.Contents(url,
[
Headers = [#"Accept"="application/json",
#"Content-Type"="application/x-www-form-urlencoded;charset=UTF-8"],
Content = Text.ToBinary("grant_type=password&username=###########&password=###########&client_id=###########&client_Secret=###########")
]
),

FormatAsJson = Json.Document(GetJson),
AccessToken = FormatAsJson[access_token],
AccessTokenHeader = "bearer " & AccessToken,

GetJson1 = Json.Document(Web.Contents(url1 , [Headers=[Authorization= AccessTokenHeader ]]))


in

GetJson1

Highlighted
New Member

Re: Issue with getting data via API with bearer token

Hope this helps

 

 

let
url = "http://###########/Portal/api/v1/Token",
url1 = "http://#########/Portal/api/v1/myapi?FromDate=2017/09/29 01:00:00&ToDate=2017/09/29 23:00:00&",

GetJson = Web.Contents(url,
[
Headers = [#"Accept"="application/json",
#"Content-Type"="application/x-www-form-urlencoded;charset=UTF-8"],
Content = Text.ToBinary("grant_type=password&username=###########&password=###########&client_id=###########&client_Secret=###########")
]
),

FormatAsJson = Json.Document(GetJson),
AccessToken = FormatAsJson[access_token],
AccessTokenHeader = "bearer " & AccessToken,

GetJson1 = Json.Document(Web.Contents(url1 , [Headers=[Authorization= AccessTokenHeader ]]))


in

GetJson1

Helpful resources

Announcements
Community Blog

Community Blog

Visit our Community Blog for articles, guides, and information created by fellow community members.

Using the Community

Using the Community

Need help with the Power BI Community? Our 'Using the Community' support articles are a great place to start.

Community Summit North America

Community Summit North America

Innovate, Collaborate, Grow. The top training and networking event across the globe for Microsoft Business Applications

Power Platform 2020 release wave 2 plan

Power Platform 2020 release wave 2 plan

Features releasing from October 2020 through March 2021

Top Solution Authors
Top Kudoed Authors