在编程用户创建后无法登录ASP.NET身份2站点

Lor*_*pts 13 asp.net-mvc asp.net-mvc-5 asp.net-identity-2

我有一个新的MVC 5剃须刀,使用ASP.NET Identity 2作为会员系统的EF 6 Web应用程序.当我使用网页上的"注册"链接手动创建用户时,它就可以了.我可以创建用户,然后我可以使用给定的密码登录然后注销.

我不知道如何将数据库初始化程序与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(); 
Run Code Online (Sandbox Code Playgroud)

因此,如果我尝试使用电子邮件地址和Test_2013密码登录帐户,则会收到错误消息,指出用户名/密码不正确.

Lor*_*pts 34

经过对实际数据库(身份2)和网络的大量调查后,我得出结论,没有人知道:)事实上,数百万网站已经过时的身份信息,甚至已经过时的Identity 2.0代码,我不得不挖掘进一步使用SQL事件探查器和SQL Management Studio.

在Identity 2.0中有一个Id属性,它是一个nvarchar()但实际上包含一个Guid.我想知道微软为什么不把它变成一个独特的标识类型?!当我应该单独放置它时,我设置了这个属性(让它自动生成它).

同样在Identity 2.0中有一个UserName字段,我填充了用户名.似乎UserName应该与Email相同,否则尝试登录将会失败.

  • 非常感谢您添加关于用户名的最后一部分必须与电子邮件相同.你已经解决了我的问题! (7认同)

Geo*_*ggg 16

我也遇到了这个压力很大的问题.它必须与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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

你可以看到

"等待SignInManager.PasswordSignInAsync(model.Email,model.Password,model.RememberMe,shouldLockout:false);"

包括Email作为第一个参数,但如果你检查PasswordSignInAsync的定义,你会发现它必须接收用户名作为第一个参数而不是电子邮件.

它默认工作,因为注册新用户的方法将属性(用户名和电子邮件)设置为等于用户提供的电子邮件值.但是,如果以编程方式保存新用户并将用户名和电子邮件设置为不同的值,则登录将失败.

这绝对是一个错误 - > MS < - "我信任那些家伙并花了几个小时试图让它工作,直到我怀疑他们"

所以你现在知道该做什么:1)更改你的登录方法以传递用户名作为第一个参数ir change注册方法以保存用户名和电子邮件不同的值.我希望它可以帮助别人.


小智 10

LoginViewModel中存在错误.如果你看一下Login方法(发布版本),PasswordSignInAsync方法的第一个参数应该是用户名,但是在loginViewModel中我们有电子邮件.

显然,你无法使它正常工作,因为PasswordSignInAsync实际上是将第一个参数视为用户名,而不是电子邮件地址,并且在LoginViewModel中有一个电子邮件验证器用于Email属性.

例如,您必须将LoginViewModel的电子邮件属性重命名为UserName,并删除EmailAddress注释.

然后在相应的登录视图中,您必须替换电子邮件输入字段并改为使用UserName.

然后在AccountController的login方法中,使用model.UserName作为第一个参数,它现在应该可以正常工作.