【问题标题】:Using UserManager.FindAsync with a custom UserStore将 UserManager.FindAsync 与自定义 UserStore 一起使用
【发布时间】:2015-07-26 09:01:49
【问题描述】:

我已经实现了一个自定义的UserStore,它实现了IUserStore<DatabaseLogin, int>IUserPasswordStore<DatabaseLogin, int>

我的登录操作方法如下:

if (ModelState.IsValid)
{
    if (Authentication.Login(user.Username, user.Password))
    {
        DatabaseLogin x = await UserManager.FindAsync(user.Username, user.Password);
        DatabaseLogin Login = Authentication.FindByName(user.Username);
        if (Login != null)
        {
            ClaimsIdentity ident = await UserManager.CreateIdentityAsync(Login,
                DefaultAuthenticationTypes.ApplicationCookie);
            AuthManager.SignOut();
            AuthManager.SignIn(new AuthenticationProperties
            {
                IsPersistent = false
            }, ident);
            return RedirectToAction("Index", "Home");
        }
    }
    else
    {
        ModelState.AddModelError("", "Invalid Login");
    }
}
return View();

在我编写的自定义身份验证类Authentication 中,我有一个运行良好的登录方法,FindByName 方法也返回一个应用用户。但是,如果我尝试使用该登录名SignIn,则不会将用户识别为已通过身份验证,并且HttpContext.User.Identity 始终为空,所以我想我必须尝试UserManager.FindAsync

这个方法调用FindByNameAsyncGetPasswordHashAsync,总是返回null。

public Task<DatabaseLogin> FindByNameAsync(string userName)
{
    if (string.IsNullOrEmpty(userName))
        throw new ArgumentNullException("userName");
    return Task.FromResult<DatabaseLogin>(Authentication.FindByName(userName));
}

public Task<string> GetPasswordHashAsync(DatabaseLogin user)
{
    if (user == null)
        throw new ArgumentNullException("user");
    return Task.FromResult<string>(user.Password);
}

还有Authentication.FindByName

public static DatabaseLogin FindByName(string name)
{
    string GetUserQuery = string.Format(
        "USE db;SELECT principal_id AS id, name as userName, create_date AS CreateDate, modify_date AS modifyDate FROM sys.database_principals WHERE type='S' AND authentication_type = 1 AND name = '{0}'"
        , name);
    DatabaseLogin user;
    using (var db = new EFDbContext())
    {
        user = db.Database.SqlQuery<DatabaseLogin>(GetUserQuery).FirstOrDefault();
    }
    user.Password = Convert.ToBase64String(Encoding.ASCII.GetBytes("pass"));
    return user;
}

如您所见,我正在使用数据库用户,我不确定如何为他们检索散列密码。目前,我只是存储正确密码的 Base65!

我不知道我哪里出错了,欢迎任何指导。

【问题讨论】:

  • 您能否将您的答案从您的问题中转移到正确的 SO 答案中?你可以自己回答。 :)

标签: c# .net asp.net-mvc asp.net-identity-2


【解决方案1】:

简短的回答:没有错。用户在其他操作方法中进行了身份验证,但显然不是在当前操作方法中。

这是我遵循的过程,也许它会帮助你调试你的应用程序。

读完source code后,FindAsync先调用FindByNameAsync,然后CheckPasswordAsync引用VerifyPasswordAsync。所以应该没问题如果我可以覆盖VerifyPasswordAsync

我创建了一个实现IPasswordHasher 的自定义password hasher,并将其注册到我的UserManagercreate 方法中,如下所示:

manager.PasswordHasher = new DbPasswordHasher();

所以现在,我可以从UserManager.FindAsync 获取我的用户,但事实证明,你从哪里获取用户并不重要,因为HttpContext.User.Identity 仍然为空!我的错误是我没有注意到用户在当前操作中没有经过身份验证,在其他操作方法中它按预期工作!

【讨论】:

  • 这对我也有用,我已经尝试了一切,直到找到你的建议,在实施 IPasswordHasher 后我让它工作了......非常感谢!
猜你喜欢
  • 2014-07-29
  • 2016-08-09
  • 2017-06-12
  • 1970-01-01
  • 2014-10-23
  • 2017-09-30
  • 2017-07-04
  • 2018-04-01
  • 1970-01-01
相关资源
最近更新 更多