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

The Power BI DataViz World Championships are on! With four chances to enter, you could win a spot in the LIVE Grand Finale in Las Vegas. Show off your skills.

Reply
clongaw
Frequent Visitor

Unable to access all needed Credentials for Refresh in OAuth flow in Custom Connector

I have a Custom Connector with a working OAuth flow. I have a working TestConnection function and am able to freely pull data. While trying to create the Refresh function for the flow, I keep running into the following error when I try to access Extension.CurrentCredential() in the Refresh function. 

[9:42:48 AM]	[Info]	RefreshCredential result {
    "Details": "Object reference not set to an instance of an object.",
    "Message": "Exception received during credential refresh.",
    "Status": "Failure"
}

 

I need to have access to the expired AccessToken, the RefreshToken, and a special Code in the function for this particular OAuth flow. I have successfully saved all the information in Extension.CurrentCredentials(), but cannot seem to pass it to the Refresh function.

[9:48:58 AM]	[Info]	ListCredentials result [
    {
        "DataSource": {
            "Kind": "OAuthTest",
            "NormalizedPath": "path",
            "Path": "path"
        },
        "AuthenticationKind": "OAuth2",
        "Properties": {
            "AccessToken": "******",
            "Expires": null,
            "RefreshToken": "******",
            "hResult": "0",
            "code": "code"
        }
    }
]

 

Here is the beginning part of the Refresh function which is causing the error. 

Refresh = (dataSourcePath, refreshToken) => 
    let
        credentials = Extension.CurrentCredential()[Properties],
        oldAccessToken = credentials[AccessToken],
        oldRefreshToken = refreshToken,
        code = credentials[code],

 

I have also tried Extension.CurrentCredential()[access_token], but continue to get the 'Object reference...' error. 

 

1 ACCEPTED SOLUTION
clongaw
Frequent Visitor

I have found a solution for my approach and have also seen another option that may be viable. The solution I am using is to set the RefreshToken in credentials as the value "access_token;refresh_token;access_code" as these are the three variables that I need. I do this by taking the TokenResult from Web.Contents and renaming or setting the Record Fields corresponding to access_token and RefreshToken:

JsonResponse = Json.Document(TokenResult),
JsonRenamed = Record.RenameFields(JsonResponse, {{"token","access_token"}, {"refreshToken", "RefreshToken"}}) & 
            [RefreshToken = JsonResponse[token] & ";" & JsonResponse[refreshToken] & ";" & code, Expires = 900]
    in
        JsonRenamed;

I can then call Refresh as 

Refresh = (dataSourcePath, tokens) => 
    let
        TokenList = Text.Split(tokens, ";"),
        accessToken = TokenList{0},
        refreshToken = TokenList{1},
        code = TokenList{2},
   ...
   in  
       output

 

The second option I have seen uses oldCredential to store and access all the old information. This is most likely cleaner, but I have not verified if it works with adding a custom field to the Credentials record to store the special access_code I need. You can see more examples of this technique here: https://community.fabric.microsoft.com/t5/Developer/Custom-Connector-failing-on-refreshing-data-with...

View solution in original post

1 REPLY 1
clongaw
Frequent Visitor

I have found a solution for my approach and have also seen another option that may be viable. The solution I am using is to set the RefreshToken in credentials as the value "access_token;refresh_token;access_code" as these are the three variables that I need. I do this by taking the TokenResult from Web.Contents and renaming or setting the Record Fields corresponding to access_token and RefreshToken:

JsonResponse = Json.Document(TokenResult),
JsonRenamed = Record.RenameFields(JsonResponse, {{"token","access_token"}, {"refreshToken", "RefreshToken"}}) & 
            [RefreshToken = JsonResponse[token] & ";" & JsonResponse[refreshToken] & ";" & code, Expires = 900]
    in
        JsonRenamed;

I can then call Refresh as 

Refresh = (dataSourcePath, tokens) => 
    let
        TokenList = Text.Split(tokens, ";"),
        accessToken = TokenList{0},
        refreshToken = TokenList{1},
        code = TokenList{2},
   ...
   in  
       output

 

The second option I have seen uses oldCredential to store and access all the old information. This is most likely cleaner, but I have not verified if it works with adding a custom field to the Credentials record to store the special access_code I need. You can see more examples of this technique here: https://community.fabric.microsoft.com/t5/Developer/Custom-Connector-failing-on-refreshing-data-with...

Helpful resources

Announcements
Las Vegas 2025

Join us at the Microsoft Fabric Community Conference

March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!

Feb2025 Sticker Challenge

Join our Community Sticker Challenge 2025

If you love stickers, then you will definitely want to check out our Community Sticker Challenge!

Feb2025 NL Carousel

Fabric Community Update - February 2025

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