我正在创建一个新的应用程序,并开始使用EF6-rc1、Microsoft.AspNet.Identity.Core 1.0.0-rc1、Microsoft.VisualAspNet_Identity.EntityFramework 1.0.0-rc2、Microsoft.AspNet.Identity.Owin 1.0.0-rcl等。随着RTM昨天的发布,我今晚通过NuGet将它们更新为RTM。
到目前为止,除了对我所做的工作进行了几次代码更改外,一切似乎都很顺利,直到我尝试为该应用程序创建一个本地用户帐户。
我一直在研究将电子邮件地址作为用户名格式,这在候选版本中非常有效,但现在当创建一个具有用户名电子邮件地址的用户时,会出现以下验证错误:
用户名xxxxx@xxxx.com无效,只能包含字母或数字。
在过去的一个小时左右,我一直在为它寻找配置选项的解决方案或文档,但都无济于事。
有没有一种方法可以将其配置为允许用户名使用电子邮件地址?
您可以通过在UserManager上插入自己的UserValidator来实现这一点,或者只需在默认实现上关闭它:
UserManager.UserValidator = new UserValidator<TUser>(UserManager) { AllowOnlyAlphanumericUserNames = false }
它的C#版本(在App_Code\IdentityModels.cs中(是
public UserManager()
: base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
{
UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
}
我遇到了同样的问题,当我试图更改代码以使用户名是个人的真实姓名而不是电子邮件时,系统向我显示相同的错误消息"用户名ABC DEF无效,只能包含字母或数字。"我解决了在AllowedUserNameCharacters中添加空格字符(在最后的例子中(的问题。
我使用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 =>
在我的案例中,在VS 2013 C#、MVC 5.2.2中运行,使用ASP.NET Identity 2.0,解决方案是在App_Start\IdentityConfig.cs中更新ApplicationUserManager构造函数,如下所示:
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
this.UserValidator = new UserValidator<ApplicationUser>(this) { AllowOnlyAlphanumericUserNames = false };
}
对于AspNet.Identity.Core 2.1及以上版本的用户,UserManager中的这些验证器是只读的。默认情况下,允许将电子邮件地址作为用户名,但如果您需要进一步自定义用户名中的字符,您可以在Startup.cs中这样做:
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity<ApplicationUser, IdentityRole>(options => {
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+/";
});
// ... etc
}
(由于遗留的原因,我需要一个"/"。(
如果您正在使用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
由于编写自己的ApplicationUserManager:UserManager类对我不起作用(也许bc我使用Razor Pages,而不是MVC(,这里有另一个解决方案:在CofigureServices((中的Startup.cs中,您可以配置标识选项,例如:
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
如果找不到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项目中生成的,这为我们提供了微软的良好指示/指导(以及一种干净的方式(,使我们能够在用户名字段中输入电子邮件。它是干净的,因为在使用Microsoft.OWIN上下文引导应用程序时,在App_Start\Startup.Auth.cs中使用了静态创建方法。
这种方法唯一不利的一面是,您最终会将电子邮件存储两次。。。。这不好!
正如您可能已经发现的(也是意料之中的(,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
如果您在帐户控制器中使用某种IOC(我使用的是StructureMap(,则在传入Usermanager时,您需要应用Hao Kung提到的修复程序:(我不得不(。在国际奥委会的设置中可能有办法做到这一点,但我不知道如何做到。
public AccountController(ApplicationUserManager userManager)
{
_userManager = userManager;
_userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
我也遇到过同样的问题。但最终我解决了这个问题,在我的方法中添加了bellow部分,而不是构造函数。
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
};
}