Configure Microsoft.AspNet.Identity para permitir o endereço de email como nome de usuário

121

Estou no processo de criação de um novo aplicativo e comecei a usar o 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 e com os lançamentos da RTM ontem, eu os atualizei via NuGet esta noite para a RTM.

Além de algumas alterações no código do trabalho que eu havia feito até agora, tudo parecia estar indo bem, até que tentei criar uma conta de usuário local para o aplicativo.

Eu estava trabalhando em endereços de email, sendo o formato de nome de usuário que, com o candidato a lançamento, funcionou muito bem, mas agora, ao criar um usuário com um endereço de email para um nome de usuário, ele gera o seguinte erro de validação:

O nome de usuário [email protected] é inválido, pode conter apenas letras ou dígitos.

Passei a última hora procurando uma solução ou documentação sobre as opções de configuração, mas sem sucesso.

Existe uma maneira de configurá-lo para permitir endereços de email para nomes de usuário?

LiamGu
fonte
1
((UserValidator<ApplicationUser>) UserManager.UserValidator).AllowOnlyAlphanumericUserNames = false;
Arvis #
possível duplicata de ASP.Net UserName para e-mail
ozz

Respostas:

164

Você pode permitir isso conectando seu próprio UserValidator no UserManager ou apenas desativando-o na implementação padrão:

UserManager.UserValidator = new UserValidator<TUser>(UserManager) { AllowOnlyAlphanumericUserNames = false }
Hao Kung
fonte
3
Como você continuaria criando um UserValidator personalizado?
teh0wner
2
Onde exatamente no código (em qual arquivo / método) (em um aplicativo mvc5 padrão) devo colocar UserManager.UserValidator = new UserValidator <TUser> (UserManager) {AllowOnlyAlphanumericUserNames = false}? Obrigado.
PussInBoots #
29
No seu AccountController, no public AccountController(UserManager<ApplicationUser> userManager)construtor addUserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager) { AllowOnlyAlphanumericUserNames = false };
LiamGu 4/13
1
@graycrow Eu continuo reclamando sobre como a associação ao Asp.net funcionou e foi fácil de usar. Eu gostava de usar o site de configuração acessível a partir de VS para ele ..
The Muffin Man
@graycrow Dado o estado atual da identidade do asp.net, anseio pelos dias do SqlMembership Provider. Para uma perspectiva maior, veja: brockallen on asp net identity
subsci
16

A versão C # disso (em App_Code \ IdentityModels.cs) é

public UserManager()
        : base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
    {
        UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
    }
user2554240
fonte
9

No meu caso, executando no VS 2013 C #, MVC 5.2.2, usando o ASP.NET Identity 2.0, a solução foi atualizar o construtor ApplicationUserManager dentro do App_Start \ IdentityConfig.cs da seguinte maneira:

public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
        this.UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
    }
N1njaB0b
fonte
5

Eu tive o mesmo problema, quando tentei alterar o código para fazer com que o nome de usuário fosse o nome real da pessoa e não o e-mail, o sistema me mostrasse a mesma mensagem de erro "O nome de usuário ABC DEF é inválido, pode conter apenas letras ou dígitos . " Resolvi o problema adicionando o caractere de espaço (no meu caso no final) a AllowedUserNameCharacters.

Estou usando o Asp.Net Core 2.2 e o VS2017

Este é o meu código

Vá para Startup.cs e edite ou adicione a linha em "// configurações do usuário":

        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
fonte
4

Se você estiver usando formulários da Web do ASP.Net e tentar fazer isso, basta abrir o arquivo IdentityModels.vb / cs e em Public Class UserManager, faça com que se pareça com:

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
fonte
4

Para as pessoas no AspNet.Identity.Core 2.1 e superior, esses validadores no UserManager são somente leitura. Os endereços de e-mail como nomes de usuário são permitidos por padrão, mas se você precisar de mais personalização dos caracteres em seus nomes de usuário, poderá fazê-lo em Startup.cs como este:

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

    // ... etc
}

(Eu precisava de um '/' por motivos legados.)

bsigma1
fonte
1

Como codificar minha própria classe ApplicationUserManager: UserManager não funcionou para mim (talvez eu use o Razor Pages, não o MVC), aqui está outra solução: No Startup.cs em CofigureServices (), você pode configurar as opções de identidade, por exemplo:

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

Mais sobre este tópico nos documentos da Microsoft: https://docs.microsoft.com/de-de/aspnet/core/security/authentication/identity-configuration?view=aspnetcore-2.2

Jimmy
fonte
0

Se você não conseguir encontrar o IdentityConfig.cs, substitua o construtor AccountController por esse código.

public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager) 
  {
      AllowOnlyAlphanumericUserNames = false  
  };
}
Suhail Mumtaz Awan
fonte
0

No meu caso, eu tinha uma classe de repositório trabalhando com autenticação, que não me permitia usar um "-" dentro de nomes de usuário. A correção estava dentro do construtor aqui:

//-------------------------------------------------------
public AuthRepository()
//-------------------------------------------------------
{
    _ctx = new AuthContext();
    _userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(_ctx));
    _userManager.UserValidator = new UserValidator<IdentityUser>(_userManager)
    {
        AllowOnlyAlphanumericUserNames = false
    };
}
Nick Kovalsky
fonte
0

Eu também fiquei preso a isso, porque na maioria das vezes os nomes de usuário são emails hoje em dia, embora eu possa entender o raciocínio de um campo de email separado. Estes são puramente meus pensamentos / experiências, pois também não consegui encontrar a opinião da Microsoft sobre isso.

Lembre-se, o Asp Identity é apenas para identificar alguém, você não precisa ter um E-mail para ser identificado, mas eles nos permitem armazená-lo porque faz parte de uma identidade. Ao criar um novo projeto da web no visual studio, você tem a opção de opções de autenticação.

Se você selecionar um tipo de projeto não vazio, como MVC, e configurar a autenticação como "Contas individuais", receberá os fundamentos básicos para o gerenciamento de usuários. Uma delas inclui uma subclasse semelhante a esta em 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
}

O que isso nos diz é que a Microsoft pretende armazenar nomes de usuário mais complexos (consulte AllowOnlyAlphaNumericUserNames = false); portanto, realmente temos sinais mistos.

O fato de isso ser gerado a partir de um projeto da web padrão nos fornece uma boa indicação / orientação da Microsoft (e de uma maneira limpa) para permitir a inserção de emails no campo nome do usuário. É limpo porque o método de criação estático é usado dentro do App_Start \ Startup.Auth.cs ao inicializar o aplicativo com o contexto Microsoft.OWIN.

A única desvantagem dessa abordagem é que você acaba armazenando o email duas vezes ... O que não é bom!

Nabster
fonte
0

Se você estiver usando algum tipo de COI (estou usando o StructureMap) no controlador de sua conta, será necessário aplicar a correção mencionada acima por Hao Kung quando o Gerenciador de usuários for passado: (eu precisava). Pode haver uma maneira de fazer isso na configuração do COI, mas não sei como.

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

Eu enfrentei o mesmo problema. mas finalmente resolvi o problema adicionando parte abaixo ao meu método, não ao construtor.

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
fonte