134

I'm in the process of creating a new application and started out using EF6-rc1, Microsoft.AspNet.Identity.Core 1.0.0-rc1, Microsoft.AspNet.Identity.EntityFramework 1.0.0-rc1, Microsoft.AspNet.Identity.Owin 1.0.0-rc1, etc and with the RTM releases yesterday, I updated them via NuGet this evening to RTM.

Apart from a couple of code changes to the work I'd done so far, all seemed to be going well, until I tried to create a local user account for the app.

I had been working on e-mail addresses being the username format which with the release candidate worked great, but now when creating a user with an email address for a username, it throws up the following validation error:

User name xxxxx@xxxx.com is invalid, can only contain letters or digits.

I've spent the last hour or so searching for a solution or documentation on configuration options for it, but to no avail.

Is there a way I can configure it to allow e-mail addresses for usernames?

TylerH
  • 20,799
  • 66
  • 75
  • 101
LiamGu
  • 5,317
  • 12
  • 49
  • 68
  • 1
    `((UserValidator) UserManager.UserValidator).AllowOnlyAlphanumericUserNames = false;` – Arvis Dec 08 '13 at 00:14
  • possible duplicate of [ASP.Net UserName to Email](http://stackoverflow.com/questions/19481835/asp-net-username-to-email) – ozz Jan 07 '14 at 09:30

13 Answers13

177

You can allow this by plugging in your own UserValidator on the UserManager, or just by turning it off on the default implementation:

UserManager.UserValidator = new UserValidator<TUser>(UserManager) { AllowOnlyAlphanumericUserNames = false }
Hao Kung
  • 28,040
  • 6
  • 84
  • 93
  • 3
    How would you go on about creating a custom UserValidator? – teh0wner Oct 20 '13 at 18:56
  • 2
    Where exactly in the code (in which file / method) (in a default mvc5 app) should I put UserManager.UserValidator = new UserValidator(UserManager) { AllowOnlyAlphanumericUserNames = false }? Thanks. – PussInBoots Nov 04 '13 at 12:39
  • 29
    In your AccountController, in the `public AccountController(UserManager userManager)` constructor add `UserManager.UserValidator = new UserValidator(UserManager) { AllowOnlyAlphanumericUserNames = false };` – LiamGu Nov 04 '13 at 14:27
  • 1
    @graycrow I keep ranting about how Asp.net membership worked and was easy to use. I enjoyed using the configuration website accessible from VS for it.. – The Muffin Man Jan 19 '14 at 01:46
  • @graycrow Given the current state of asp.net identity I long for the days of SqlMembership Provider. For a larger perspective see: [brockallen on asp net identity](http://brockallen.com/2013/10/20/the-good-the-bad-and-the-ugly-of-asp-net-identity/) – subsci Feb 11 '14 at 03:52
  • Will this open a security hole?? I would assume EF is taking care of the prevention of SQL injection part? – anIBMer Mar 24 '14 at 02:14
  • If an orm allows sql injection while only manipulating entities, it is a broken orm. Injection with an orm should only be possible when using a textual querying language (such as HQL or the little known equivalent in EF, E-SQL). And it is not that a good orm prevents it by scanning values. A good orm does not check values, it simply builds its queries in a way immune to injection. – Frédéric Oct 22 '14 at 16:02
17

The C# version of this (in App_Code\IdentityModels.cs) is

public UserManager()
        : base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
    {
        UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
    }
user2554240
  • 171
  • 1
  • 5
12

I had the same problem, when I tried to change the code for make the UserName was the real name of the person and not the email the system show me the same error message "User name ABC DEF is invalid, can only contain letters or digits." I solved the problem adding the space character (In my case at the end) to AllowedUserNameCharacters.

Im using Asp.Net Core 2.2 and VS2017

This is my code

Go to Startup.cs and edit or add the line under "//user settings":

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.Configure<IdentityOptions>(options =>
        {
            // Password settings.
            options.Password.RequireDigit = true;
            options.Password.RequireLowercase = true;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequiredLength = 6;
            options.Password.RequiredUniqueChars = 1;

            // Lockout settings.
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
            options.Lockout.MaxFailedAccessAttempts = 5;
            options.Lockout.AllowedForNewUsers = true;


            // User settings.
            options.User.AllowedUserNameCharacters =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+ ";
            options.User.RequireUniqueEmail = false;
        });

        services.ConfigureApplicationCookie(options =>
jcarrillo
  • 121
  • 1
  • 3
9

In my case, running in VS 2013 C#, MVC 5.2.2, using ASP.NET Identity 2.0, the solution was to update the ApplicationUserManager constructor inside App_Start\IdentityConfig.cs like so:

public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
        this.UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
    }
N1njaB0b
  • 688
  • 6
  • 11
8

For people on AspNet.Identity.Core 2.1 and up, these validators in the UserManager are readonly. Email addresses as usernames are allowed by default but if you need further customisation of the characters in your usernames, you can do so in Startup.cs like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentity<ApplicationUser, IdentityRole>(options => {
        options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+/";
    });

    // ... etc
}

(I needed a '/' for legacy reasons.)

bsigma1
  • 260
  • 4
  • 10
4

If you are using ASP.Net webforms and are trying to accomplish this, simply open up your IdentityModels.vb/cs file and under Public Class UserManager, have it look as so:

Public Class UserManager
Inherits UserManager(Of ApplicationUser)

Public Sub New()
    MyBase.New(New UserStore(Of ApplicationUser)(New ApplicationDbContext()))
    Users = store
    UserValidator = New UserValidator(Of ApplicationUser)(Me) With {.AllowOnlyAlphanumericUserNames = False}
End Sub

Public Property Users() As IUserStore(Of ApplicationUser)
    Get
        Return m_Users
    End Get
    Private Set(value As IUserStore(Of ApplicationUser))
        m_Users = value
    End Set
End Property
Private m_Users As IUserStore(Of ApplicationUser)

End Class
kleopatra
  • 51,061
  • 28
  • 99
  • 211
TyrolMedia
  • 41
  • 1
2

Since coding my own ApplicationUserManager : UserManager class didn't work for me (maybe bc I use Razor Pages, not MVC), here's another solution: In Startup.cs in CofigureServices() you can configure Identity Options, for example:

services.Configure<IdentityOptions>(options =>
{
  options.User.AllowedUserNameCharacters = 
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@";
  options.User.RequireUniqueEmail = true;
});

More on this topic in Microsoft docs: https://learn.microsoft.com/de-de/aspnet/core/security/authentication/identity-configuration?view=aspnetcore-2.2

Jimmy
  • 864
  • 13
  • 24
0

As you will have probably found out (and was to be expected), ASP.NET Identity 2.0.0, released March 2014, adds this functionality in the framework.

Announcement: http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx

Full example and tutorial, including account confirmation: http://www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity

Vincent Sels
  • 2,711
  • 1
  • 24
  • 31
0

If you cannot find IdentityConfig.cs then replace your AccountController constructor with this code.

public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager) 
  {
      AllowOnlyAlphanumericUserNames = false  
  };
}
Suhail Mumtaz Awan
  • 3,295
  • 8
  • 43
  • 77
0

In my case i had a repository class working with authentication, that didn't let me use a "-" inside usernames.. The fix was inside the constructor here:

//-------------------------------------------------------
public AuthRepository()
//-------------------------------------------------------
{
    _ctx = new AuthContext();
    _userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(_ctx));
    _userManager.UserValidator = new UserValidator<IdentityUser>(_userManager)
    {
        AllowOnlyAlphanumericUserNames = false
    };
}
Nick Kovalsky
  • 5,378
  • 2
  • 23
  • 50
0

I was also stuck with this because most of the time usernames are E-mails these days, I can understand the reasoning of a separate E-mail field though. These are purely my thoughts / experience as I also could not find Microsoft's say on this.

Remember, Asp Identity is purely to identify someone, you don't have to have an E-mail to be identified but they allow us to store it because it forms part of an identity. When you create a new web project in visual studio, you are given the option for authentication options.

If you select a non empty project type such as MVC and set authentication to "Individual accounts" then you are given the basic underpinnings for user management. One of which includes a sub class looking like this within App_Start\IdentityConfig.cs:

 // Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
    }
    //N.B rest of code removed
}

What this tells us is that Microsoft intend us to store more complex usernames (refer to AllowOnlyAlphaNumericUserNames = false), so really we have mixed signals.

The fact this is generated from a default web project gives us a good indication / direction from Microsoft (and a clean way) to enable us to enter E-mails for the username field. It's clean because the static create method is used within the App_Start\Startup.Auth.cs when bootstrapping the application with the Microsoft.OWIN context.

The only down side to this approach is you end up storing the E-mail twice.... Which is not good!

Nabster
  • 95
  • 7
0

If you are using IOC of some sort ( I am using StructureMap) in your account controller, you will need to apply the fix mentioned above by Hao Kung when the Usermanager is passed in: (I had to). There may be a way to do it in the IOC setup, but I don't know how.

public AccountController(ApplicationUserManager userManager)
    {
        _userManager = userManager;
        _userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
davaus
  • 1,145
  • 13
  • 16
0

I have faced the same problem . but finally I resolved the issue by adding bellow part in to my method , not the constructor .

public void MyMethod(){

     UserManager<ApplicationUser> manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));


                    // Configure validation logic for usernames  
                    manager.UserValidator = new UserValidator<ApplicationUser>(manager)
                    {
                        AllowOnlyAlphanumericUserNames = false,
                        RequireUniqueEmail = true

                    };         

}