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

Find everything you need to get certified on Fabric—skills challenges, live sessions, exam prep, role guidance, and more. Get started

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
Fabcon_Europe_Social_Bogo

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.

Power BI Carousel June 2024

Power BI Monthly Update - June 2024

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

PBI_Carousel_NL_June

Fabric Community Update - June 2024

Get the latest Fabric updates from Build 2024, key Skills Challenge voucher deadlines, top blogs, forum posts, and product ideas.

RTI Forums Carousel3

New forum boards available in Real-Time Intelligence.

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