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

Get certified in Microsoft Fabric—for free! For a limited time, the Microsoft Fabric Community team will be offering free DP-600 exam vouchers. Prepare now

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
OCT PBI Update Carousel

Power BI Monthly Update - October 2024

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

September Hackathon Carousel

Microsoft Fabric & AI Learning Hackathon

Learn from experts, get hands-on experience, and win awesome prizes.

October NL Carousel

Fabric Community Update - October 2024

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

Top Solution Authors