The ultimate Fabric, Power BI, SQL, and AI community-led learning event. Save €200 with code FABCOMM.
Get registeredEnhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends August 31st. Request your voucher.
Hi everyone!
I'm trying to build my first custom connector using oauth to show data from an api. I don't have any error messages but after clickin on login to set my credentials...
... it opens the login on my web app
...but it gets stuck there like i'm accesing it from a browser, it doesn't return to the first image to let me connect and see the information on power bi!
I'm not sure if i'm missing some method to handle the proccess after the authentication. Here's the snippet of my code...
client_id = Text.FromBinary(Extension.Contents("client_id"));
client_secret = Text.FromBinary(Extension.Contents("client_secret"));
redirect_uri = "https://oauth.powerbi.com/views/oauthredirect.html";
authorize_uri = "https://.../oauth/authorize?";
token_uri = "https://.../oauth/access_token";
logout_uri = "https://login.microsoftonline.com/logout.srf";
windowWidth = 1200;
windowHeight = 1000;
scope_prefix = "";
scopes = {
"daily"
};
DataSource.Kind = "GithubSample", Publish = "GithubSample.UI"]
shared GithubSample.Contents = Value.ReplaceType(Github.Contents, type function (url as Uri.Type) as any);
[DataSource.Kind = "GithubSample"]
shared GithubSample.PagedTable = Value.ReplaceType(
Github.PagedTable, type function (url as Uri.Type) as nullable table
);
GithubSample = [
TestConnection = (dataSourcePath) => {"GithubSample.Contents", dataSourcePath},
Authentication = [
OAuth = [
StartLogin = StartLogin,
FinishLogin = FinishLogin,
Refresh=Refresh,
Logout=Logout
]
],
Label = Extension.LoadString("AuthenticationLabel")
];
GithubSample.UI = [
Beta = true,
ButtonText = {Extension.LoadString("FormulaTitle"), Extension.LoadString("FormulaHelp")},
SourceImage = GithubSample.Icons,
SourceTypeImage = GithubSample.Icons
];
GithubSample.Icons = [
Icon16 = {
Extension.Contents("github16.png"),
Extension.Contents("github20.png"),
Extension.Contents("github24.png"),
Extension.Contents("github32.png")
},
Icon32 = {
Extension.Contents("github32.png"),
Extension.Contents("github40.png"),
Extension.Contents("github48.png"),
Extension.Contents("github64.png")
}
];
Value.IfNull = (a, b) => if a <> null then a else b;
GetScopeString = (scopes as list, optional scopePrefix as text) as text =>
let
prefix = Value.IfNull(scopePrefix, ""),
addPrefix = List.Transform(scopes, each prefix & _),
asText = Text.Combine(addPrefix, " ")
in
asText;
Github.Contents = (url as text) =>
let
content = Web.Contents(url),
link = GetNextLink(content),
json = Json.Document(content),
table = Table.FromList(json, Splitter.SplitByNothing())
in
table meta [Next = link];
Github.PagedTable = (url as text) =>
Table.GenerateByPage(
(previous) =>
let
urlToUse = if (next <> null) then next else url,
current = if (previous <> null and next = null) then null else Github.Contents(urlToUse),
link = if (current <> null) then Value.Metadata(current)[Next] else null
in
current meta [Next = link]
);
GetNextLink = (response, optional request) =>
let
link = Value.Metadata(response)[Headers][#"Link"]?,
links = Text.Split(link, ","),
splitLinks = List.Transform(links, each Text.Split(Text.Trim(_), ";")),
next = List.Select(splitLinks, each Text.Trim(_{1}) = "rel=""next"""),
first = List.First(next),
removedBrackets = Text.Range(first{0}, 1, Text.Length(first{0}) - 2)
in
try removedBrackets otherwise null;
StartLogin = (resourceUrl, state, display) =>
let
AuthorizeUrl = authorize_uri
& Uri.BuildQueryString(
[
client_id = client_id,
scope = "user, repo",
state = state,
redirect_uri = redirect_uri
]
)
in
[
LoginUri = AuthorizeUrl,
CallbackUri = redirect_uri,
WindowHeight = windowHeight,
WindowWidth = windowWidth,
Context = null
];
FinishLogin = (context, callbackUri, state) => let Parts = Uri.Parts(callbackUri)[Query] in TokenMethod(Parts[code]);
TokenMethod = (code) =>
let Response = Web.Contents(
token_uri,
[
Content = Text.ToBinary(
Uri.BuildQueryString(
[
client_id = client_id,
client_secret = client_secret,
code = code,
redirect_uri = redirect_uri
]
)
),
Headers = [#"Content-type" = "application/x-www-form-urlencoded", #"Accept" = "application/json"]
]
),
Parts = Json.Document(Response)
in
Parts;
Refresh = (resourceUrl, refresh_token) => TokenMethod("refresh_token", "refresh_token", refresh_token);
Logout = (token) => logout_uri;
Table.GenerateByPage = (getNextPage as function) as table =>
let
listOfPages = List.Generate(
() => getNextPage(null), (lastPage) => lastPage <> null, (lastPage) => getNextPage(lastPage)
),
tableOfPages = Table.FromList(listOfPages, Splitter.SplitByNothing(), {"Column1"}),
firstRow = tableOfPages{0} ?
in
if (firstRow = null) then
Table.FromRows({})
else
Value.ReplaceType(
Table.ExpandTableColumn(tableOfPages, "Column1", Table.ColumnNames(firstRow[Column1])),
Value.Type(firstRow[Column1])
);
I appreciate your help with my problem!
Solved! Go to Solution.
Hi @paocohe ,
Please check the following aspects:
Check Redirect URI: Ensure that the redirect_uri specified in your code matches exactly with the one registered in your OAuth app settings. It must be whitelisted and correctly configured on the server side to redirect back to Power BI.
Validate Authentication Flow: The OAuth flow requires a correct sequence of steps, starting with user authorization, obtaining an access token, and then using that token to access resources. Please review the steps in the OAuth 2.0 authentication with Power BI documentation to ensure your flow matches the expected pattern.
Power BI REST APIs for embedded analytics and automation - Power BI REST API | Microsoft Learn
Inspect Callback Handling: After the service authenticates the user, it should redirect the user-agent back to the redirect_uri provided. The service will append an authorization code to this URI, which your code should then exchange for an access token. Verify that your service is correctly appending the code and that your FinishLogin function is correctly extracting and using this code.
Perhaps you could provide the version of Power BI Desktop you have and a screenshot of the interface where you are experiencing the problem. Thank you!
Best Regards,
Dino Tao
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.
Actually your first suggestion solved the issue! Thanks 🙂
Hi @paocohe ,
Please check the following aspects:
Check Redirect URI: Ensure that the redirect_uri specified in your code matches exactly with the one registered in your OAuth app settings. It must be whitelisted and correctly configured on the server side to redirect back to Power BI.
Validate Authentication Flow: The OAuth flow requires a correct sequence of steps, starting with user authorization, obtaining an access token, and then using that token to access resources. Please review the steps in the OAuth 2.0 authentication with Power BI documentation to ensure your flow matches the expected pattern.
Power BI REST APIs for embedded analytics and automation - Power BI REST API | Microsoft Learn
Inspect Callback Handling: After the service authenticates the user, it should redirect the user-agent back to the redirect_uri provided. The service will append an authorization code to this URI, which your code should then exchange for an access token. Verify that your service is correctly appending the code and that your FinishLogin function is correctly extracting and using this code.
Perhaps you could provide the version of Power BI Desktop you have and a screenshot of the interface where you are experiencing the problem. Thank you!
Best Regards,
Dino Tao
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.