Skip to content

[Bug]: OAuth unable to bind email to user #1322

Closed
@placidic

Description

@placidic

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

I have a successful GENERIC OAuth Implementation for Lowcoder against Microsoft Entra ID.

When a new user is created automatically upon first login of the user, the new lowcoder-user object is not populating the email property. Furthermore, if the logged in user clicks the Profile Icon and attempts to manually bind the email address to the current user, an "Oops, service is busy" error message appears and the binding fails.
image

I can confirm that the GENERIC data contained in the user object contains the email address value - but the local user email is blank.
image

With the new Lowcoder login experience in v2.5.0, this is causing issues when the user is trying to log in using the standard user login path. The email is unable to be found in the local lowcoder database and stops the user from proceeding.

There is a workaround however to still use the old workspace specific login path - once you go there, you still only see the Email Input, but if you enter an email address and click "Continue" it then refreshes and renders the SSO Buttons configured for that workspace. An extra step to log in now with 2.5.0, but at least accessible.

Expected Behavior

I would expect that upon first login of the new user, the email address returned from the OAuth provider would be automatically bound to the lowcoder user object.

Steps to reproduce

  1. Set up Generic OAuth Provider with MS Entra ID - using 'email' for email binding
  2. Obtain an Invite link for a new user
  3. Log in using the invite link via SSO for the new User
  4. Log out and try to log back in using the email address returned from the SSO Binding

Environment

Lowcoder 2.5.0 Self-Hosted

Additional Information

No response

Activity

self-assigned this
on Nov 22, 2024
moved this to 🆕 New in Lowcoderon Nov 22, 2024
FalkWolsky

FalkWolsky commented on Nov 22, 2024

@FalkWolsky
Contributor

We have a question: Did you use the mapping in Step 3 and map by a JSON path the field eMail?
Please have a look here. Either the access_token or the userInfo Endpoint have the eMail in the JSON objects available. By this binding and a classic JSON notation like user.data.email (just as example) - you can address the eMail and it will get bound automatically.

Screenshot 2024-11-22 at 22 13 01
placidic

placidic commented on Nov 22, 2024

@placidic
Author

I do have it mapped:
image

And if I look at my currentUser state, it shows the email under the GENERIC attributes:
image

After inspecting my jwt token, i then realized that there was no 'email' property returned in my token!
My assumption is that the email is getting returned during the user introspection call after authorization.
Although i'm sending the scope for 'email' it just allows permissions to it, but does not return it in the initial token response.

Would it be possible to update the local email address based on the result of a user introspection call in the case that user introspection is enabled?

At least I think i know why its not working =)

FalkWolsky

FalkWolsky commented on Nov 22, 2024

@FalkWolsky
Contributor

This is actually what we (aim) to do. If we do not find the eMail based on the JSON Path you entered there - but if we then get the JSON by the user introspection Request, we take the eMail from there. Please check the JSON structure of the user introspection endpoint and adapt the JSON path in the Source Mapping as you expect all fields there would come from the user introspection endpoint

FalkWolsky

FalkWolsky commented on Nov 22, 2024

@FalkWolsky
Contributor

Idea behind this "manual binding" is to give great flexibility for many possible providers and integrations.

placidic

placidic commented on Nov 22, 2024

@placidic
Author

I'll try out a few variations and confirm. What's odd is that the current name of the email returned from user introspection is 'email' based on what shows under the extras=>GENERIC section under the currentUser object, which is how I have it mapped in the source mapping.

Thanks for the feedback and I'll let you know!

FalkWolsky

FalkWolsky commented on Nov 22, 2024

@FalkWolsky
Contributor

We also have to try again. If it not works as intended - then we will fix it.

added a commit that references this issue on Nov 27, 2024

#1322: Fix object comparing using Objects.equals()

placidic

placidic commented on Dec 3, 2024

@placidic
Author

Thanks for the tip @dragonpoo, I initially I was unsure what property would be ideal to map to the user id but the sub property does make more sense.

I pulled the latest dev image released about 12 hours ago in dockerhub, updated my SSO mapping to use sub (which would also force a new user to be created), hoping that the referenced merged (1322) would resolve my email binding issue.

As expected, the new user is created and added to the workspce, but unfortunately, the lowcoder user is not created with the email property populated, however the email still correctly shows in the extended OIDC properties within the extras section as before.

I've also confirmed that within my user introspection response, the email address is returned with the same mapped property name 'email'

placidic

placidic commented on Dec 3, 2024

@placidic
Author

including a screenshot of my user introspection response, showing the 'email' property
image

placidic

placidic commented on Dec 5, 2024

@placidic
Author

Updated to the latest 2.5.1 image:
If I attempt to bind the email address after oauth signup, I get the following error:
image

In the logs I see the following error has occurred

2024-12-05 16:39:53.369 ERROR o.l.api.framework.exception.GlobalExceptionHandler#lambda$doLog$9:175 POST /api/auth/email/bind [nioEventLoopGroup-3-1]:
org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND
at org.springframework.web.reactive.DispatcherHandler.lambda$createNotFoundError$3(DispatcherHandler.java:159)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:45)
at reactor.core.publisher.Mono.subscribe(Mono.java:4568)
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82)
...

If i look in my developer tools within lowcoder - I see the matching email entered within the oauth element for the user.
image

From what you wrote it sounds like the expectation that the user creates an account FIRST via email, and THEN login via oAuth and then bind the 2 accounts together?

That doesn't seem like it would be a requirement, as when a new oAuth user is created upon first login, the other user properties are transferred to the new account upon creation, but not the email address (which is only available from the user introspection token as our jwt token does not include that information).

It was mentioned that as long as the value binding naming matched the property in either the jwt or user introspection reponse (in my case 'email') That it should transfer over like the Name property which is populating successfully on first login. Is this not supported today?

5 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

BugSomething isn't workingJava BackendPull requests that update Java code

Type

No type

Projects

Status

✅ Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    [Bug]: OAuth unable to bind email to user · Issue #1322 · lowcoder-org/lowcoder