FusionAuth / fusionauth-issues

FusionAuth issue submission project
https://fusionauth.io
91 stars 12 forks source link

Possible to create multiple users with same Login #1874

Open epbensimpson opened 2 years ago

epbensimpson commented 2 years ago

Possible to create multiple users with same Login

Description

I was under the impression that the Login for a user must be unique, but it appears this is not the case. It is entirely possible to create a user with a username that is an email with no email address, and another user with that same email as the email address.

This affects both manually creating users and linking strategies (which is how this issue was brought to our attention). Our application enforces the uniqueness when creating users, but then the linking strategy violates this.

After the duplicate accounts are created, it is no longer possible to log in using the password for the account with the username until the account with the email address is deleted.

Affects versions

1.36.8

Steps to reproduce

Steps to reproduce the behavior:

  1. Set up the Google IdP and configure it with Link on email, create the user if they do not exist
  2. Create a user with a Gmail address as their username, and no email address
  3. Sign in via Google using that Gmail account
  4. A duplicate account now exists

or

  1. Create a user with an email address as their username, with no email address
  2. Create a user with the same email address as their email, and no username
  3. A duplicate account now exists

Expected behavior

Should not be allowed to create a duplicate account.

Screenshots

image

Platform

Community guidelines

All issues filed in this repository must abide by the FusionAuth community guidelines.

Additional context

User 1:

{
  "active" : true,
  "connectorId" : "e3306678-a53a-4964-9040-1c96f36dda72",
  "encryptionScheme" : "bcrypt",
  "id" : "d7252306-dfbe-4ff1-89f5-d472f1ad0dbe",
  "insertInstant" : 1655244958632,
  "lastLoginInstant" : 1656625672732,
  "lastUpdateInstant" : 1663019699625,
  "passwordChangeRequired" : false,
  "passwordLastUpdateInstant" : 1655244958711,
  "registrations" : [ {
    "applicationId" : "53770139-f524-c00a-26fe-b950fb0fe91e",
    "id" : "608acfac-0b49-458e-a846-5f8082936c6c",
    "insertInstant" : 1655244958714,
    "lastLoginInstant" : 1656625672732,
    "lastUpdateInstant" : 1656625672741,
    "usernameStatus" : "ACTIVE",
    "verified" : true
  } ],
  "tenantId" : "c28e67d2-44c8-911b-0566-c3484c11b1d8",
  "twoFactor" : { },
  "uniqueUsername" : "ben.simpson.<removed>@gmail.com",
  "username" : "ben.simpson.<removed>@gmail.com",
  "usernameStatus" : "ACTIVE",
  "verified" : true
}

User 2:

{
    "active" : true,
    "connectorId" : "e3306678-a53a-4964-9040-1c96f36dda72",
    "email" : "ben.simpson.<removed>@gmail.com",
    "encryptionScheme" : "bcrypt",
    "id" : "6e6e7f70-a0b5-4db4-a603-0edcffbdfc67",
    "insertInstant" : 1663020669411,
    "lastLoginInstant" : 1663021777560,
    "lastUpdateInstant" : 1663020669411,
    "passwordChangeRequired" : false,
    "passwordLastUpdateInstant" : 1663020669489,
    "registrations" : [ {
      "applicationId" : "53770139-f524-c00a-26fe-b950fb0fe91e",
      "id" : "44a59695-0228-42ca-af3e-6e440002d30a",
      "insertInstant" : 1663021777560,
      "lastLoginInstant" : 1663021777560,
      "lastUpdateInstant" : 1663021777560,
      "usernameStatus" : "ACTIVE",
      "verified" : true
    } ],
    "tenantId" : "c28e67d2-44c8-911b-0566-c3484c11b1d8",
    "twoFactor" : { },
    "usernameStatus" : "ACTIVE",
    "verified" : true
  }
robotdan commented 2 years ago

This is sort of working as designed, the users are still discrete, and do not share the same login - but I understand the issue it creates.

In general we leave it up to the user of FusionAuth to decide if they wish to utilize email or username for login.

The way to solve the issue currently is to limit your implementation to utilize email or username, but not both. Or - perform additional validation outside of FusionAuth if allowing a users to specify an username.

We could also explore new features to allow integrations to utilize both a username and email, such as:

An existing feature that would also help you is Unique Usernames. Tenants > Edit > General > Username settings > Unique usernames. This feature may or may not work for you, it is more common in the gaming industry to allow everyone to be batman if they so choose - so each username is automatically augmented with a random suffix to become unique. Example: batman#42.

epbensimpson commented 2 years ago

Fair enough, as mentioned we do ensure the username/email is mutually unique (across different users) when creating users through our application but the issue for us is mostly when users log in via an IdP with "Link on email, create user if they do not exist" strategy. We can avoid this for now by changing it to "Do not create user if they do not exist" but that may not be viable in the future.

It's probably a coincidence but worth nothing that we only started getting reports of this happening after switching to FusionAuth-hosted login pages this week. Previously for Google (the main source of pain here) we were just using the Identity Provider Login API with the ID token to complete the login and I'm not aware of this being an issue :thinking:

robotdan commented 2 years ago

A couple more thoughts.

One option for you would be to use the "Create Pending Link" linking strategy. This would allow you to authenticate via Google and then the user would be prompted to login or create a user. In this way, if you want the user to utilize a username during registration this could be enforced via the self-service path.

But in a general sense, if you have this issue - it likely means you have at least one integration where you are allowing the user to enter a username for login purposes. Ideally you would choose one or the other - email or username. If you want both, but not for login then there are a few options:

If you were to primarily want to utilize username as the unique Id in your integration - another option we could think about building is a new linking strategy which is essentially the "Create a pending link" but allow the user to register without a password. In this case, the user would authenticate via Google which uses email as their unique Id - and then we would allow the user to complete the login process in FusionAuth by only filling in the missing information i.e. a username to complete the link.

epbensimpson commented 2 years ago

We're considering the pending link route but that may be too complicated for our users.

What about a tenant-level configuration option that enforces the mutual uniqueness of these fields across different users? Just don't make me bend over backwards to enforce something that seems like it should be fairly obvious functionality.