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

Grow your Fabric skills and prepare for the DP-600 certification exam by completing the latest Microsoft Fabric challenge.

Reply
AxelBAndersen
Frequent Visitor

Avoid Authorization headers when using Credential Type UsernamePassword

I use UsernamePassword to get information needed to build the uri string in a custom connector. The Password bit is unique for the file I want to retrieve when combined with the uri part in the Username bit.

No matter how I try to avoid Authorization in the headers (adding ManualCredentials = true to the Web.Contents() call), my call fails with: 

 

 

 

Authentication is not given in the correct format. Check the value of Authorication header

 

 

 

I also tried adding the entire uri with credential type Key, but here I'm also not able to avoid the Authorization in the headers.

 

If I change credential type to anonymous and hard-code the uri in my connector, the data is retrieved as expected.

 

Is there a way to reset the "magic" headers when doing Web.Contents(uri) with UsernamePassword or Key Credential Type?

5 REPLIES 5
AxelBAndersen
Frequent Visitor

What I am really trying to do is thes:

 

[DataSource.Kind="MyConnector", Publish="MyConnector.Publish"]
shared MyConnector.Contents = () as table =>
    let
        baseUri = try Extension.CurrentCredential()[Username] otherwise "https://MyEndpoint",
        token = try Extension.CurrentCredential()[Password] otherwise "MySecretToken"
    in    
        GetMyData(baseUri, token);

MyConnector = [
    Authentication = [
         UsernamePassword = [
            UsernameLabel = "Url",
            PasswordLabel = "SecretToken"
         ],
        Implicit = []
    ],
    Label = "Uri token access"
];

GetMyData = (uri, token) =>
	let
	_uri = uri & '?' & token
	source = Json.Document(Web.Contents(_uri)),
	value = source[value],
	ConvertedToTable = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
	fieldNames = Record.FieldNames(ConvertedToTable{0}[Column1]),
	final = Table.ExpandRecordColumn(ConvertedToTable, "Column1", fieldNames, fieldNames)

 in
	final;

 

When running this with Credential Type Anonymous it returns the data from my url, but when running it with the UsernamePassword Credential Type, I get the Authentication error.

 

This leads me to the assumption, that the Password part is set in the authentication header of the Web client in the MyConnector.Contents function based on the connection type I chose.

 

According to the documentation found here: Handling authentication for Power Query connectors | Microsoft Docs

M data source functions that have been enabled for extensibility will automatically inherit your extension's credential scope.

 

Is it possible to break this inheritance and get an Anonymous function execution within a UsernamePassword credential scope?

Hi @AxelBAndersen ,

Seems like you are trying to create custom connector, not familiar with this aspect but have some ideas by myself that you may refer to.

 

Since the document mentioned that M data source would do it automatically so that it could not have a direct way to break this inheritance currently.

 

I have found Inheriting auth explaination in PostMan document: Inheriting auth 

An example using OAuth: GitHub Connector Sample 

 

In addition, since using username and password to authenticate but you want to use Web.Contents(), whether there is a way to convert them to a bearer token and then use it in the headers for authorazation.

 

Best Regards,
Community Support Team _ Yingjie Li
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

The OAuth sample adds nothing new.

 

I would love to be able to have the enduser of my custom connector to be able to input url and secrettoken, without that effecting my Web.Contents() object. Actually I find it a bit strange, that I  can customize the labels that are presented to the enduser but I do not control how those values are used in the code.

 

Right now I have "solved" the issue with a file in the root folder, which is included in the mez file. It just feels SO wrong to have to ask the user to unzip and update that file, when they receive the seret token. Especially given that the enduser interface supports custom UsernamePassword input.

 

According to the documentation found here: Web.Contents - PowerQuery M | Microsoft Docs

 

it should be possible exclude specific headers with the ExcludedFromCacheKey option. Chris Webb has an example on that here: Chris Webb's BI Blog: Web.Contents(), Caching And The ExcludedFromCacheKey Option In Power BI And Po...

 

Unfortunately, I still get the same error when running:

```

GetMyData = (uri, token) =>
	let
	_uri = uri & '?' & token
	source = Json.Document(Web.Contents(_uri), [ExcludedFromCacheKey = {"Authorization"}])

```

v-yingjl
Community Support
Community Support

Hi @AxelBAndersen ,

In Web.Contents() function, the second optional parameter could include multiple contents, like query, relative path, Headers etc. Authorization is in the Headers.

Basically the format could be like this:

Web.Contents(url,[Relative path = "xx",Query = "xxx", Headers= [#"Authorization" = xxx, #"Content-Type" = xxx])

For Username and password authentication, you can use Extension.CurrentCredential() to access current credentials.

You can refer this blog and document which provides examples:

  1. Using OpenApi.Document() To Create A Power BI Custom Connector For The Power BI REST API 
  2. Handling Authentication 

 

About authentication, it could be like this mentioned by the document:

Authentication = [
    OAuth = [
        StartLogin = StartLogin,
        FinishLogin = FinishLogin,
        Refresh = Refresh,
        Logout = Logout
    ],
    Key = [],
    UsernamePassword = [],
    Windows = [],
    Implicit = []
]

 

Best Regards,
Community Support Team _ Yingjie Li
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Hi v-yingjl,

 

Thank you so much for supporting me on this case!

 

My situation is, that I want the user of my connector to enter a "username" and a "password" that I then stitch togeather to form a pre-authenticated uri.

 

I do get the vairables populated by the initial authentication. However, when passing the 2 variables to the next fundtion, where I use Web.Contents, the header in the function call seems to have a "magic" authentication header, that I cannot get rid of.

 

I tired:

 

Headers = []

 


but I still get Authentication is not given in the correct format.

 

I'm customed to C# and other object orientated languages. I'm really missing a debut feature on Power BI that let's me inspect the Web.Contents call before it is executed. Is there a tool that let's me inspect the code just before the call is executed? With such a tool I could inspect the headers before the command is executed - and surely find a fix for the "magic" header.

Helpful resources

Announcements
RTI Forums Carousel3

New forum boards available in Real-Time Intelligence.

Ask questions in Eventhouse and KQL, Eventstream, and Reflex.

MayPowerBICarousel1

Power BI Monthly Update - May 2024

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

Europe Fabric Conference

Europe’s largest Microsoft Fabric Community Conference

Join the community in Stockholm for expert Microsoft Fabric learning including a very exciting keynote from Arun Ulag, Corporate Vice President, Azure Data.

Top Solution Authors
Top Kudoed Authors