dotnet / dotnet/aspnetcore

Support email as login identifier in Identity API endpoints

Open
#68,662 4 comments 1 reaction 0 assignees View on GitHub
api-proposal api-suggestion area-identity
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

## Background and Motivation

The default Identity API endpoints (added in .NET 8 via `AddIdentityApiEndpoints`) are built around a username-based login system. The `/login` endpoint accepts an `email` field in its JSON body, but internally passes that value to `UserManager.FindByNameAsync`. This only works correctly when the application sets `UserName = Email` at registration time.

Many applications need a separate username (e.g., a handle or display name) while still letting users log in with their email address. Today, developers have to work around this by:

- Overriding `UserManager.FindByNameAsync` to redirect email-based lookups.
- Replacing the login endpoint entirely.
- Forcing `UserName = Email`, giving up a distinct username.

This proposal adds a simple configuration flag to `IdentityOptions` that tells the default login endpoint to treat email as the login identifier. This preserves a separate username where needed and removes repetitive boilerplate for what is a very common scenario.

## Proposed API

Add a new boolean property to `IdentityOptions`:

```diff
namespace Microsoft.AspNetCore.Identity;

public class IdentityOptions
{
+ ///
+ /// Gets or sets a flag indicating whether the login process should use email
+ /// as the primary identifier instead of username. When true, the default
+ /// Identity API login endpoint looks up users by email.
+ ///
+ public bool UseEmailForLogin { get; set; }
}
```

The default value is `false`, preserving existing behavior. When set to `true`, the built-in login endpoint calls `FindByEmailAsync` instead of `FindByNameAsync`.

## Usage Examples

```csharp
// Program.cs
builder.Services.AddIdentityApiEndpoints(options =>
{
options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultPhoneProvider;
options.UseEmailForLogin = true; // enable email login
});

app.MapIdentityApi();
```

Registration can still accept a separate username (or the application can generate one). Once the flag is enabled, a login request like:

```json
{
"email": "john@example.com",
"password": "P@ssw0rd!"
}
```

successfully authenticates the user by email, even when the stored `UserName` differs.

## Alternative Designs

**New extension method** (e.g., `AddIdentityApiEndpointsWithEmailLogin`) — Duplicates existing setup and adds more API surface than necessary; less discoverable than a simple option.

## Risks

- **No breaking changes** — Default value is `false`, so existing applications are unaffected.
- **Scope beyond API endpoints** — If other Identity surfaces (e.g., Razor Pages UI) also respect this flag, that may be a welcome feature rather than a risk, but it should be an explicit, intentional decision rather than an accidental side effect.

Contributor guide

Open the contributing guide

Research direction

Start from the AddIdentityApiEndpoints and MapIdentityApi entry points, then trace the default /login endpoint and IdentityOptions handling. Confirm how the endpoint currently uses FindByNameAsync, identify the relevant Identity API tests, and consider the documented scope for other Identity surfaces. Done means the new option defaults to existing behavior and enables email lookup when set to true.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, authentication
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.