Skonfiguruj Microsoft.AspNet.Identity, aby zezwolić na adres e-mail jako nazwę użytkownika

121

Jestem w trakcie tworzenia nowej aplikacji i zacząłem od EF6-rc1, Microsoft.AspNet.Identity.Core 1.0.0-rc1, Microsoft.AspNet.Identity.EntityFramework 1.0.0-rc1, Microsoft.AspNet.Identity Win 1.0.0-rc1, itd., A przy wczorajszych wydaniach RTM zaktualizowałem je za pośrednictwem NuGet dzisiejszego wieczoru do RTM.

Oprócz kilku zmian kodu w pracy, którą wykonałem do tej pory, wszystko wyglądało na dobrze, dopóki nie spróbowałem utworzyć lokalnego konta użytkownika dla aplikacji.

Pracowałem nad adresami e-mail będącymi formatem nazwy użytkownika, który z kandydatem do wydania działał świetnie, ale teraz podczas tworzenia użytkownika z adresem e-mail dla nazwy użytkownika pojawia się następujący błąd walidacji:

Nazwa użytkownika [email protected] jest nieprawidłowa, może zawierać tylko litery lub cyfry.

Spędziłem mniej więcej godzinę na poszukiwaniu rozwiązania lub dokumentacji na temat opcji konfiguracyjnych, ale bezskutecznie.

Czy istnieje sposób, w jaki mogę go skonfigurować, aby zezwalał na adresy e-mail dla nazw użytkowników?

LiamGu
źródło
1
((UserValidator<ApplicationUser>) UserManager.UserValidator).AllowOnlyAlphanumericUserNames = false;
Arvis,
możliwy duplikat nazwy użytkownika ASP.Net na e
ozz

Odpowiedzi:

164

Możesz na to zezwolić, podłączając swój własny UserValidator do UserManager lub po prostu wyłączając go w domyślnej implementacji:

UserManager.UserValidator = new UserValidator<TUser>(UserManager) { AllowOnlyAlphanumericUserNames = false }
Hao Kung
źródło
3
Jak postępowałbyś w tworzeniu niestandardowego UserValidator?
teh0wner
2
Gdzie dokładnie w kodzie (w którym pliku / metodzie) (w domyślnej aplikacji mvc5) należy umieścić UserManager.UserValidator = new UserValidator <TUser> (UserManager) {AllowOnlyAlphanumericUserNames = false}? Dzięki.
PussInBoots
29
W swoim kontrolerze konta, w public AccountController(UserManager<ApplicationUser> userManager)konstruktorze dodajUserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager) { AllowOnlyAlphanumericUserNames = false };
LiamGu
1
@graycrow Ciągle narzekam na to, jak członkostwo Asp.net działa i jest łatwe w użyciu. Podobało mi się używanie strony konfiguracyjnej dostępnej w VS dla niego ..
The Muffin Man,
@graycrow Biorąc pod uwagę bieżący stan tożsamości asp.net, tęsknię za dniami dostawcy SqlMembership. Dla szerszej perspektywy zobacz: brockallen on asp net identity
subsci
16

Wersja C # this (w App_Code \ IdentityModels.cs) to

public UserManager()
        : base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
    {
        UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
    }
user2554240
źródło
9

W moim przypadku, działając w VS 2013 C #, MVC 5.2.2, używając ASP.NET Identity 2.0, rozwiązaniem była aktualizacja konstruktora ApplicationUserManager wewnątrz App_Start \ IdentityConfig.cs w następujący sposób:

public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
        this.UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
    }
N1njaB0b
źródło
5

Miałem ten sam problem, kiedy próbowałem zmienić kod, aby nazwa użytkownika była prawdziwym imieniem osoby, a nie adresem e-mail, system wyświetla ten sam komunikat o błędzie "Nazwa użytkownika ABC DEF jest nieprawidłowa, może zawierać tylko litery lub cyfry . ” Rozwiązałem problem dodając znak spacji (w moim przypadku na końcu) do AllowedUserNameCharacters.

Używam Asp.Net Core 2.2 i VS2017

To jest mój kod

Przejdź do Startup.cs i edytuj lub dodaj wiersz pod „// 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
źródło
4

Jeśli korzystasz z formularzy internetowych ASP.Net i próbujesz to osiągnąć, po prostu otwórz plik IdentityModels.vb / cs i pod Public Class UserManager, niech to wygląda tak:

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
TyrolMedia
źródło
4

W przypadku osób korzystających z AspNet.Identity.Core 2.1 i nowszych te walidatory w UserManager są tylko do odczytu. Adresy e-mail jako nazwy użytkowników są domyślnie dozwolone, ale jeśli potrzebujesz dalszego dostosowania znaków w swoich nazwach użytkowników, możesz to zrobić w Startup.cs w następujący sposób:

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

    // ... etc
}

(Potrzebowałem znaku „/” ze względu na starsze wersje).

bsigma1
źródło
1

Ponieważ kodowanie mojej własnej klasy ApplicationUserManager: UserManager nie zadziałało dla mnie (może bc używam Razor Pages, a nie MVC), oto inne rozwiązanie: W Startup.cs w CofigureServices () możesz skonfigurować opcje tożsamości, na przykład:

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

Więcej na ten temat w Microsoft Docs: https://docs.microsoft.com/de-de/aspnet/core/security/authentication/identity-configuration?view=aspnetcore-2.2

Jimmy
źródło
0

Jeśli nie możesz znaleźć IdentityConfig.cs, zastąp konstruktora AccountController tym kodem.

public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager) 
  {
      AllowOnlyAlphanumericUserNames = false  
  };
}
Suhail Mumtaz Awan
źródło
0

W moim przypadku miałem klasę repozytorium pracującą z uwierzytelnianiem, która nie pozwoliła mi użyć znaku „-” w nazwach użytkowników. Poprawka znajdowała się w konstruktorze tutaj:

//-------------------------------------------------------
public AuthRepository()
//-------------------------------------------------------
{
    _ctx = new AuthContext();
    _userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(_ctx));
    _userManager.UserValidator = new UserValidator<IdentityUser>(_userManager)
    {
        AllowOnlyAlphanumericUserNames = false
    };
}
Nick Kovalsky
źródło
0

Utknąłem z tym również, ponieważ obecnie większość nazw użytkowników to e-maile, ale rozumiem uzasadnienie oddzielnego pola E-mail. To są wyłącznie moje przemyślenia / doświadczenia, ponieważ nie mogłem też znaleźć zdania Microsoftu na ten temat.

Pamiętaj, że tożsamość Asp służy wyłącznie do identyfikacji kogoś, nie musisz mieć adresu e-mail, aby zostać zidentyfikowanym, ale pozwalają nam go przechowywać, ponieważ stanowi część tożsamości. Podczas tworzenia nowego projektu internetowego w programie Visual Studio masz możliwość wyboru opcji uwierzytelniania.

Jeśli wybierzesz niepusty typ projektu, taki jak MVC, i ustawisz uwierzytelnianie na „Konta indywidualne”, otrzymasz podstawowe podstawy zarządzania użytkownikami. Jedna z nich zawiera podklasę wyglądającą tak w ramach 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
}

To mówi nam, że Microsoft zamierza przechowywać bardziej złożone nazwy użytkowników (patrz AllowOnlyAlphaNumericUserNames = false), więc tak naprawdę mamy mieszane sygnały.

Fakt, że jest on generowany z domyślnego projektu internetowego, daje nam dobrą wskazówkę / wskazówkę od firmy Microsoft (i przejrzysty sposób), aby umożliwić nam wprowadzenie adresów e-mail w polu nazwy użytkownika. Jest czysty, ponieważ statyczna metoda tworzenia jest używana w App_Start \ Startup.Auth.cs podczas ładowania aplikacji w kontekście Microsoft.OWIN.

Jedyną wadą tego podejścia jest dwukrotne przechowywanie wiadomości e-mail… Co nie jest dobre!

Nabster
źródło
0

Jeśli używasz jakiegoś IOC (używam StructureMap) w kontrolerze swojego konta, będziesz musiał zastosować poprawkę wspomnianą powyżej przez Hao Kunga, kiedy Usermanager zostanie przekazany: (musiałem). Może istnieć sposób, aby to zrobić w konfiguracji IOC, ale nie wiem jak.

public AccountController(ApplicationUserManager userManager)
    {
        _userManager = userManager;
        _userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
davaus
źródło
0

Miałem ten sam problem. ale w końcu rozwiązałem problem, dodając poniżej część do mojej metody, a nie konstruktora.

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

                    };         

}
sachith walpita
źródło