我有一个新的 MVC 5 razor, EF 6 Web应用程序,使用 ASP.NET Identity 2 作为成员资格系统。当我使用网页上的“注册”链接手动创建用户时,它就可以了。我可以创建用户,然后我可以使用给定的密码登录,然后注销。
我不知道如何将数据库初始化程序与Identity 2的迁移一起使用,有无数的Identity 1和其他alpha和beta版本的例子只会让人感到困惑。由于我还不知道,我使用临时MVC视图来安装成员资格。
我看到视图正常执行,我看到用户和角色以及用户与数据库中角色的关联。我还看到用户在记录中有一个哈希密码。
但是,在执行之后,我无法使用Create方法中使用的纯文本密码登录身份系统(本地),为什么?顺便说一下,我省略了try / catch并检查用户和角色创建(它们执行时没有错误)。
DbContext ctx = ApplicationDbContext.Create();
transaction = ctx.Database.BeginTransaction();
RoleManager<IdentityRole> roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(ctx));
var roleAdmin = roleManager.Create(new IdentityRole("Admin"));
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(ctx));
ApplicationUser userAdmin = new ApplicationUser { Id = "admin", Email = "me@there.com", UserName = "admin" };
userManager.Create(userAdmin, "Test_2013");
userManager.AddToRole(userAdmin.Id, "Admin");
userManager.Update(userAdmin);
transaction.Commit();
因此,如果我尝试使用电子邮件地址和Test_2013密码登录帐户,则会收到错误消息,指出用户名/密码不正确。
答案 0 :(得分:32)
经过对实际数据库(身份2)和网络的大量调查后,我得出结论,没有人知道:)实际上数以百万计的网站已经过时了有关身份的信息,甚至放置已经过时的Identity 2.0代码我必须使用SQL事件探查器和SQL Management Studio进一步深入研究。
在Identity 2.0中,有一个Id属性,它是一个nvarchar()但实际上包含一个Guid。我想知道为什么微软没有把它变成一个独特的标识类型?!我在设置这个属性的时候应该把它单独放下(让它自动生成它)。
同样在Identity 2.0中有一个UserName字段,我填充了用户名。似乎UserName应该与Email相同,否则尝试登录将会失败。
答案 1 :(得分:14)
我也遇到了这个压力很大的问题。它必须使用在AccountsController中创建的默认Login方法:
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
你可以看到
“等待SignInManager.PasswordSignInAsync( model.Email ,model.Password,model.RememberMe,shouldLockout:false);”
包含电子邮件作为第一个参数,但如果您检查 PasswordSignInAsync 的定义,您会看到必须接收用户名作为第一个参数而不是电子邮件。
默认情况下它起作用,因为注册新用户的方法将属性(用户名和电子邮件)设置为等于用户提供的电子邮件值。但是,如果以编程方式保存新用户并将用户名和电子邮件设置为不同的值,则登录将失败。
这无论如何都是来自 - &gt;的错误MS&lt; - “我信任那些家伙并花了几个小时试图让它工作,直到我怀疑他们”
所以你现在知道该做什么:1)更改你的登录方法以传递用户名作为第一个参数ir change注册方法以保存用户名和电子邮件不同的值。 我希望它可以帮助别人。
答案 2 :(得分:10)
LoginViewModel中存在错误。 如果你看一下Login方法(发布版本),PasswordSignInAsync方法的第一个参数应该是用户名,但是在loginViewModel中我们有电子邮件。
显然,你无法使其正常工作,因为PasswordSignInAsync实际上是将第一个参数视为用户名,而不是电子邮件地址,并且在LoginViewModel中有一个电子邮件验证器用于Email属性。
例如,您必须将LoginViewModel的电子邮件属性重命名为UserName,并删除EmailAddress注释。
然后在相应的登录视图中,您必须替换电子邮件输入字段并改为使用UserName。
然后在AccountController的login方法中,使用model.UserName作为第一个参数,它现在应该可以正常工作。