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

Compete to become Power BI Data Viz World Champion! First round ends August 18th. Get started.

Reply
asingh1-tibco
Regular Visitor

Passing User Input to StartLogin and FinishLogin in Power BI Custom Connector

I am working on a custom Power BI connector and have defined authParams as optional authentication parameters, which include ClientID, ClientSecret, TenantID, RedirectURL, and Scope. These serve as custom input fields where users provide authentication details.

I want to pass the user input from authParams to my StartLogin and FinishLogin functions for authentication. However, I am unsure how to correctly access and use these values within the authentication flow.

Here is my sample code:

 

section Custom.PBI.Connector;

[DataSource.Kind = "Custom.PBI.Connector", Publish = "Custom.PBI.Connector.Publish"]
shared Custom.PBI.Connector.DataSource = Value.ReplaceType(ConnectionImpl, ConnectionType);

// Define Connection Implementation
ConnectionImpl = (dsn as text, optional advancedOptions as text, optional options as record, optional authParams as record) =>
    let
        Credential = Extension.CurrentCredential(),
        AuthKind = Credential[AuthenticationKind]?,
        CredentialConnectionString =
            if AuthKind = "UsernamePassword" then
                [
                    UID = Credential[Username],
                    PWD = Credential[Password]
                ]
            else
                [],
        
        ConnectionStringPartial = [
            DSN = dsn
        ] & CredentialConnectionString,

        ConnectionString = RecordToString(ConnectionStringPartial)
            & ";"
            & (if advancedOptions <> null then advancedOptions else ""),

        OAuthOptions =
            if AuthKind = "OAuth" then
                let
                    AccessToken = Credential[access_token]?
                in
                    if AccessToken = null then
                        error "Access Token is missing. Please authenticate again."
                    else
                        [CredentialConnectionString = RecordToString([AccessToken = AccessToken])]
            else
                [],

        finalDatasource =
            try
                if HasQuery(options) then
                    Odbc.Query(ConnectionString, options[Query])
                else
                    Odbc.DataSource(ConnectionString, OAuthOptions)
            otherwise
                error "Failed to connect. Please check your credentials and network settings.",

        PersistedResult = if finalDatasource <> null then finalDatasource else error "No data returned."
    in
        PersistedResult;

// Define ConnectionType
ConnectionType = type function (
    dsn as text,
    optional advancedOptions as text,
    optional options as record,
    optional authParams as record
) as table;

// Define OAuth Login Handling
StartLogin = (resourceUrl, state, display) =>
    let
        authUrl = "https://login.provider.com/" & tenant_id & "/oauth2/authorize?",
        queryString = Uri.BuildQueryString([
            client_id = client_id,
            redirect_uri = redirect_uri,
            response_type = "code",
            scope = scope,
            state = state
        ]),
        AuthorizeUrl = authUrl & queryString
    in
        [
            LoginUri = AuthorizeUrl,
            CallbackUri = redirect_uri,
            WindowHeight = 720,
            WindowWidth = 1024,
            Context = null
        ];

FinishLogin = (context, callbackUri, state) =>
    let
        parts = Uri.Parts(callbackUri)[Query],
        result =
            if Record.HasFields(parts, {"error", "error_description"}) then
                error Error.Record(parts[error], parts[error_description], parts)
            else
                ExchangeAuthorizationCode(parts[code])
    in
        result;

ExchangeAuthorizationCode = (authCode as text) as record =>
    let
        tokenUrl = "https://login.provider.com/" & tenant_id & "/oauth2/token",
        queryParams = [
            grant_type = "authorization_code",
            code = authCode,
            redirect_uri = redirect_uri,
            client_id = client_id,
            client_secret = client_secret
        ],
        tokenResponse = Web.Contents(tokenUrl, [
            Content = Text.ToBinary(Uri.BuildQueryString(queryParams)),
            Headers = ["Content-Type" = "application/x-www-form-urlencoded", "Accept" = "application/json"]
        ]),
        body = Json.Document(tokenResponse),
        result =
            if Record.HasFields(body, {"error", "error_description"}) then
                error Error.Record(body[error], body[error_description], body)
            else
                body
    in
        result;

// Publish Data Source UI Details
Custom.PBI.Connector.Publish = [
    Beta = false,
    Category = "Custom",
    ButtonText = {"Connect", "Connect to a custom data source"},
    LearnMoreUrl = "https://yourdocumentationlink.com",
    SupportsDirectQuery = true
];

 

 

How can I retrieve these user-provided values in my StartLogin and FinishLogin functions and use them dynamically in the authentication process? Any guidance or examples would be greatly appreciated.

Thanks in advance!

1 ACCEPTED SOLUTION

This didn't help to solve my problem. but I have made the below changes that resolved my issue. 

 

MyCustomConnector = [
TestConnection = (dataSource) =>
let
jsonDoc = Json.Document(dataSource),

DSN = Record.FieldOrDefault(jsonDoc, "dsn", ""),
AuthURL = Record.FieldOrDefault(jsonDoc, "auth_url", null),
TokenURL = Record.FieldOrDefault(jsonDoc, "token_url", null),
ClientID = Record.FieldOrDefault(jsonDoc, "client_id", null),
ClientSecret = Record.FieldOrDefault(jsonDoc, "client_secret", null),
RedirectURL = Record.FieldOrDefault(jsonDoc, "redirect_url", null),
Scope = Record.FieldOrDefault(jsonDoc, "scope", null),

hasOAuth = (AuthURL <> null and TokenURL <> null and ClientID <> null and ClientSecret <> null and RedirectURL <> null and Scope <> null),

ConnectionDetails = if hasOAuth then
{
"Custom.DataSource",
DSN,
AuthURL,
TokenURL,
ClientID,
ClientSecret,
RedirectURL,
Scope
}
else
{
"Custom.DataSource",
DSN
}
in
ConnectionDetails,

Authentication = [
UsernamePassword = [],
Windows = [SupportsAlternateCredentials = true],
Implicit = [],
OAuth = [
StartLogin = StartLogin,
FinishLogin = FinishLogin,
Refresh = RefreshToken,
Label = "Organizational Account"
]
],

Label = Extension.LoadString("ConnectorDisplayName")
];

View solution in original post

6 REPLIES 6
v-pgoloju
Community Support
Community Support

Hi @asingh1-tibco,

 

We wanted to kindly check in to see if everything is working as expected after trying the suggested solution. If there’s anything else we can assist with, please don’t hesitate to ask.

If the issue is resolved, we’d appreciate it if you could mark the helpful reply as Accepted Solution — it helps others who might face a similar issue.

 

Warm regards,

Prasanna Kumar

v-pgoloju
Community Support
Community Support

Hi @asingh1-tibco,

 

As we haven’t heard back from you, we wanted to kindly follow up to check if the solution provided for the issue worked? or Let us know if you need any further assistance?

If our response addressed, please mark it as Accept as solution and click Yes if you found it helpful.

 

Regards,

Prasanna Kumar

v-pgoloju
Community Support
Community Support

@asingh1-tibco ,

Thank you for reaching out on the Microsoft Fabric Community Forum.

Define Your Custom Auth UI

[DataSource.UI.Prompts]

Custom.PBI.Connector = [

    CredentialPrompt = [

        AuthenticationKind = "OAuth",

        Label = "Enter your OAuth Details",

        Fields = [

            client_id = [Label = "Client ID", Type = "Text"],

            client_secret = [Label = "Client Secret", Type = "Text", IsPassword = true],

            tenant_id = [Label = "Tenant ID", Type = "Text"],

            redirect_uri = [Label = "Redirect URI", Type = "Text"],

            scope = [Label = "Scope", Type = "Text"]

        ]

    ]

];

 

Define OAuth Authentication Kind
In your DataSource.Kind metadata

[DataSource.Kind = "Custom.PBI.Connector"]
shared Custom.PBI.Connector = ... // your data source

Custom.PBI.Connector = [
Authentication = [
OAuth = [
StartLogin = StartLogin,
FinishLogin = FinishLogin,
Label = Extension.LoadString("OAuthLabel")
]
]
];

 

3. Update StartLogin
StartLogin = (resourceUrl, state, display) =>
let
creds = Extension.CurrentCredential(),
client_id = creds[client_id],
tenant_id = creds[tenant_id],
redirect_uri = creds[redirect_uri],
scope = creds[scope],
authUrl = "https://login.provider.com/" & tenant_id & "/oauth2/authorize?",
queryString = Uri.BuildQueryString([
client_id = client_id,
redirect_uri = redirect_uri,
response_type = "code",
scope = scope,
state = state
])
in
[
LoginUri = authUrl & queryString,
CallbackUri = redirect_uri,
WindowHeight = 720,
WindowWidth = 1024,
Context = null
];

 

Update FinishLogin and ExchangeAuthorizationCode
FinishLogin = (context, callbackUri, state) =>
let
creds = Extension.CurrentCredential(),
parts = Uri.Parts(callbackUri)[Query],
result =
if Record.HasFields(parts, {"error", "error_description"}) then
error Error.Record(parts[error], parts[error_description], parts)
else
ExchangeAuthorizationCode(parts[code], creds)
in
result;

ExchangeAuthorizationCode = (authCode as text, creds as record) as record =>
let
tokenUrl = "https://login.provider.com/" & creds[tenant_id] & "/oauth2/token",
queryParams = [
grant_type = "authorization_code",
code = authCode,
redirect_uri = creds[redirect_uri],
client_id = creds[client_id],
client_secret = creds[client_secret]
],
tokenResponse = Web.Contents(tokenUrl, [
Content = Text.ToBinary(Uri.BuildQueryString(queryParams)),
Headers = [
"Content-Type" = "application/x-www-form-urlencoded",
"Accept" = "application/json"
]
]),
body = Json.Document(tokenResponse),
result =
if Record.HasFields(body, {"error", "error_description"}) then
error Error.Record(body[error], body[error_description], body)
else
body
in
result;

 

 

If this response is helpful, please consider marking it as the accepted solution and giving it a thumbs-up to help others in the community.

Thank you!

This didn't help to solve my problem. but I have made the below changes that resolved my issue. 

 

MyCustomConnector = [
TestConnection = (dataSource) =>
let
jsonDoc = Json.Document(dataSource),

DSN = Record.FieldOrDefault(jsonDoc, "dsn", ""),
AuthURL = Record.FieldOrDefault(jsonDoc, "auth_url", null),
TokenURL = Record.FieldOrDefault(jsonDoc, "token_url", null),
ClientID = Record.FieldOrDefault(jsonDoc, "client_id", null),
ClientSecret = Record.FieldOrDefault(jsonDoc, "client_secret", null),
RedirectURL = Record.FieldOrDefault(jsonDoc, "redirect_url", null),
Scope = Record.FieldOrDefault(jsonDoc, "scope", null),

hasOAuth = (AuthURL <> null and TokenURL <> null and ClientID <> null and ClientSecret <> null and RedirectURL <> null and Scope <> null),

ConnectionDetails = if hasOAuth then
{
"Custom.DataSource",
DSN,
AuthURL,
TokenURL,
ClientID,
ClientSecret,
RedirectURL,
Scope
}
else
{
"Custom.DataSource",
DSN
}
in
ConnectionDetails,

Authentication = [
UsernamePassword = [],
Windows = [SupportsAlternateCredentials = true],
Implicit = [],
OAuth = [
StartLogin = StartLogin,
FinishLogin = FinishLogin,
Refresh = RefreshToken,
Label = "Organizational Account"
]
],

Label = Extension.LoadString("ConnectorDisplayName")
];

v-prasare
Community Support
Community Support

Hi @asingh1-tibco,

Thanks for reaching out to MS Fabric community support

 

Power BI Custom Connectors do not directly support passing user-defined authentication parameters (authParameters) into StartLogin and FinishLogin at runtime. But you can work around this limitation using Static Parameters and Custom Authentication Records.

 

 

 

Thanks,

Prashanth Are

MS Fabric community support

 

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly and give Kudos if helped you resolve your query

Thanks for the response. If possible can you please guide with sample code to solve this issue.

Helpful resources

Announcements
August Power BI Update Carousel

Power BI Monthly Update - August 2025

Check out the August 2025 Power BI update to learn about new features.

August 2025 community update carousel

Fabric Community Update - August 2025

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