Auth0 as an external identity provider (medplum ca...
# support
o
Im implementing auth0 as an external identity provider, and the testing seems to work except that medplum cannot find a corresponding user {"resourceType":"OperationOutcome","issue":[{"severity":"error","code":"invalid","details":{"text":"User not found"}}],"extension":[{"url":"https://medplum.com/fhir/StructureDefinition/tracing","extension":[{"url":"requestId","valueId":"4a6ca053-81fc-41b2-a7aa-7d6dc8ecb331"},{"url":"traceId","valueId":"1-687402b3-48d7d02e4fe5f88770635220"}]}]} I am using the login demo repo (https://github.com/medplum/medplum-client-external-idp-demo) and have a practioner resource using the email address that is being used to login to auth0. I noticed that emails on practitioners and patients cannot be used as the id since you can make multiple patients and practitioners with the same email addresses. Does this mean a patient or practitioner resource is not enough to let a patient or practitioner login, and I need to additionally create a "User" resource? I looked into that and creating a User resource to test this, but the "email" field is greyed out and says "read-only", so I cannot create a User with a given email address. Besides, I would like to use the auth0 id (ie auth0|123xyz...) not the email, so we can do passwordless (email or sms etc). Thanks
r
Was the user invited with the auth0 External ID? https://www.medplum.com/docs/auth/methods/external-ids
o
@rahul1 ok, I tried more things, and it was indeed related to a patient or practitioner not being a "user" in the app like when you "invite" them. After making them users, the external idp demo works. So that solves "login" with the external idp. My next question is concerning user account creation. Currently, a patient or practitioner goes to our site, they fill out forms in our UI, we then send the data to our own backend. Our backend then takes the data and creates a local db account using our own db with no medical data on it, creates a medplum user with the given userType and the data, and then manually creates a matching auth0 user. Is this correct, or is medplum supposed to create the auth0 account automatically when we create a medplum user?
@reshma we have patient sign up enabled since it is a patient facing app
r
The invite with the externalID as shown in the doc is the path you want I believe. Which means that the auth0 account comes first and then the externalId is added to the Medplum /invite
o
We are creating medplum users programatically like so const scimPatientUser = await medplum.post("scim/v2/Users", { schemas: ["urn:ietf:params:scim:schemas:core:2.0:User"], userType: "Patient", name: { givenName: patientContactAndDemographics.firstName || "unknown", familyName: patientContactAndDemographics.lastName || "unknown", }, emails: [ { value: patientContactAndDemographics.email, }, ], externalId: auth0User.user_id, externalIdIssuer: Auth0Service.getDomain(), });
Not inviting per say
How can I clear the login flow? When I click the "login" button that triggers medplum.signInWithExternalAuth, I have no way to try different accounts, it just immediately goes to "https://api.medplum.com/auth/external?code/state/projectId/redirectUri (i removed the values)
ie, how do I log it out so that it prompts me again with the login screen
r
Hi @oscadev , I think there might be some confusion. The SCIM endpoints are typically used to connect IDPs like Auth0 programatically regsiter users with Medplum
To invite from your backend, you can use our Admin Auth APIs: https://www.medplum.com/docs/auth/user-management-guide#invite-via-api
The reason you might be getting a "user not found" would be if you hadn't registered a user, with the same email, in Medplum before logging in with Auth0
o
@rahul1 ignore every previous message since there is out of date data: Here is the current scenario 1) The reason for "user not found" is because we were not creating users before. We were just creating "patients" and "practioniers". Once I created a "user", it no longer complained about not finding a user. 2) Our flow is the patient fills our forms, and submits the data to our own backend. Then the backend creates a medplum user with the data, as well as a local db user with ouwn db, and then also creates a matching auth0 user. My question is: Is this correct, or should medplum be creating the auth0 user itself since we setup the external IDP. 3) How can I reset the medplum.signInWithExternalAuth flow? Once I sign in, I never see the login prompt again and so cannot login as a different user (it just keeps signing in to the same auth0 user for ever without prompt)
m
@oscadev For your third point, I believe you can use medplum.signOut() to be able to log in again as a different user
For your second point, yes, medplum should be creating the auth0 user itself since you set up the external idp
o
@Maddy hmm, I am creating users like so const scimPatientUser = await medplum.post("scim/v2/Users", { schemas: ["urn:ietf:params:scim:schemas:core:2.0:User"], userType: "Patient", name: { givenName: patientContactAndDemographics.firstName || "unknown", familyName: patientContactAndDemographics.lastName || "unknown", }, emails: [ { value: patientContactAndDemographics.email, }, ], externalId: auth0User.user_id, externalIdIssuer: Auth0Service.getDomain(), }); in our backend, and the user gets created in medplum, but not in auth0. Do you think something is wrong with my post here, or perhaps something is wrong in my medplum external IDP setup? Thanks!
r
Hi Oscar, hoping we can help here: > 1) The reason for "user not found" is because we were not creating users before. We were just creating "patients" and "practioniers". Once I created a "user", it no longer complained about not finding a user. Great, glad this part is solved > 2) Our flow is the patient fills our forms, and submits the data to our own backend. Then the backend creates a medplum user with the data, as well as a local db user with ouwn db, and then also creates a matching auth0 user. My question is: Is this correct, or should medplum be creating the auth0 user itself since we setup the external IDP. > This is correct. When using an external IDP, it will serve as the source of truth for user identities, and Medplum will be downstream.
> 3) How can I reset the medplum.signInWithExternalAuth flow? Once I sign in, I never see the login prompt again and so cannot login as a different user (it just keeps signing in to the same auth0 user for ever without prompt) So what's happening here is that here is that even though the user is logged out Medplum, they are still logged into Auth0. Because Auth0 is a separate entity that can be used for multiple apps, you will need to have the user log ou tof Auth0 seperately. This SO post might be helpful https://stackoverflow.com/questions/12909332/how-to-logout-of-an-application-where-i-used-oauth2-to-login-with-google
> const scimPatientUser = await medplum.post("scim/v2/Users", { > schemas: One point of clarification here, you typically wouldn't call the SCIM endpoints from your own app. The SCIM is an automated protocol for Auth0 to add/remove users in Medplum automatically (https://auth0.com/docs/authenticate/protocols/scim). This maybe be an option for you If your app is creating users manually, you should use our
/admin/invite
endpoints: https://www.medplum.com/docs/auth/user-management-guide#invite-via-api
o
@rahul1 thanks for all that. A lot of things have been resolved, so this is the current status: logout and login are working, but I am still creating auth0 users manually. Another medplum user said that medplum should be creating the auth0 users itself. Here is my current setup 1) a user signs up using our own form which goes to our backend 2) our backend creates the medplum user using await medplum.post("scim/v2/Users", also creates a local user in our own db, and lastly creates an auth0 user. After this, logging in works. I dont like the separate steps since issues can arise, such as one of the 3 failing to create, and so we have broken users that cant login. Just double checking that this is the way to do it, and that medplum itself cannot create an auth0 user so its a one-shot and in sync. Thanks a lot
155 Views