配置 Microsoft.AspNet.Identity 以允许电子邮件地址作为用户名

我正在创建一个新的应用程序,并开始使用 EF6-rc1,微软。AspNet.身份。内核1.0.0-rc1,Microsoft。AspNet.身份。微软 EntityFramework 1.0.0-rc1。AspNet.身份。Owin 1.0.0-rc1等等昨天发布的 RTM 版本,我今天晚上通过 NuGet 更新到 RTM。

除了我目前为止所做的一些代码更改之外,一切似乎都进展顺利,直到我尝试为这个应用程序创建一个本地用户帐户。

我一直在研究电子邮件地址作为用户名格式,这种格式在发布候选版本时效果很好,但是现在,当为用户名创建一个具有电子邮件地址的用户时,它会抛出以下验证错误:

用户名 xxxxx@xxx.com 无效,只能包含字母或数字。

我已经花了大约一个小时的时间搜索关于它的配置选项的解决方案或文档,但是没有结果。

有没有什么方法可以配置为允许用户名使用电子邮件地址?

55140 次浏览

您可以通过在 UserManager 上插入您自己的 UserValidator 来实现这一点,或者只需在默认实现上关闭它:

UserManager.UserValidator = new UserValidator<TUser>(UserManager) { AllowOnlyAlphanumericUserNames = false }

如果您正在使用 ASP.Net 网络表单,并试图完成这一任务,只需打开 IdentityModels.vb/cs 文件,并在 Public Class UserManager 下显示如下:

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

这个程序的 C # 版本(在 App _ code identitymodels.cs 中)是

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

正如您可能已经发现的(也是预料之中的) ,2014年3月发布的 ASP.NET Identity 2.0.0在框架中添加了这个功能。

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

完整的例子和教程,包括帐户确认: http://www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity

在我的案例中,运行在 VS 2013 C # ,MVC 5.2.2中,使用 ASP.NET Identity 2.0,解决方案是在 App _ Start 中更新 ApplicationUserManager 构造函数, identityconfig.cs 如下:

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

如果找不到 identityconfig.cs ,那么用这段代码替换 AccountController 构造函数。

public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager)
{
AllowOnlyAlphanumericUserNames = false
};
}

在我的例子中,我有一个使用身份验证的存储库类,它不允许我在用户名中使用“-”。.补丁在这里的构造函数中:

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

我也被这个问题困住了,因为现在大多数时候用户名都是电子邮件,不过我可以理解单独的电子邮件字段的理由。这些纯粹是我的想法/经验,因为我也找不到微软在这方面的发言权。

请记住,Asp Identity 纯粹是为了识别某人,你不需要有一个电子邮件来被识别,但他们允许我们存储它,因为它形成了一个身份的一部分。当您在 VisualStudio 中创建一个新的 Web 项目时,您可以选择身份验证选项。

如果您选择一个非空项目类型,如 MVC,并设置身份验证为“个人帐户”,那么您将获得用户管理的基本基础。其中一个子类在 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
}

这告诉我们,微软希望我们存储更复杂的用户名(参见 AllowOnlyAlphaNumericUserNames = false) ,所以我们实际上有混合的信号。

事实上,这是由一个默认的 web 项目生成的,这为我们提供了一个来自微软的很好的指示/方向(和一个干净的方式) ,使我们能够输入用户名字段的电子邮件。它是干净的,因为在 App _ Start Startup 中使用了 static create 方法。Auth.cs 在使用 Microsoft.OWIN 上下文引导应用程序时。

这种方法的唯一缺点是最终会存储两次电子邮件... ... 这不是好事!

如果您在帐户控制器中使用某种 IOC (我使用的是 structureMap) ,那么当传入用户管理器时,您需要应用 郝公提到的修复程序: 在国际奥委会的体系中可能有一种方法可以做到这一点,但我不知道该怎么做。

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

为 AspNet 上的人准备的。身份。在核心2.1及以上版本中,UserManager 中的这些验证器是只读的。默认情况下允许使用电子邮件地址作为用户名,但如果需要进一步定制用户名中的字符,可以在 Startup.cs 中这样做:

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


// ... etc
}

(出于遗留问题的原因,我需要一个“/”。)

我也遇到过同样的问题。但是最后我通过在方法中添加下面的部分而不是构造函数来解决这个问题。

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


};


}

由于编写我自己的 ApplicationUserManager: UserManager 类对我不起作用(也许我使用 Razor Pages,而不是 MVC) ,这里有另一个解决方案: 在 CofigureServices ()的 Startup.cs 中,你可以配置 Identity Options,例如:

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

Microsoft 文档中关于此主题的更多信息: https://learn.microsoft.com/de-de/aspnet/core/security/authentication/identity-configuration?view=aspnetcore-2.2

我有同样的问题,当我试图改变代码使用户名是真正的名字的人,而不是电子邮件系统显示我相同的错误消息“用户名 ABC DEF 是无效的,只能包含字母或数字。”我解决了将空格字符(在我的例子中是在最后)添加到 AllowedUserNameProperties 的问题。

我用的是 Asp.Net Core 2.2和 VS2017

这是我的原则

转到 Startup.cs,编辑或添加“//用户设置”下的行:

        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 =>