简体   繁体   English

结合使用UserManager.FindAsync和自定义UserStore

[英]Using UserManager.FindAsync with a custom UserStore

I have implemented a custom UserStore , it implements IUserStore<DatabaseLogin, int> and IUserPasswordStore<DatabaseLogin, int> . 我已经实现了自定义UserStore ,它实现了IUserStore<DatabaseLogin, int>IUserPasswordStore<DatabaseLogin, int>

My Login action method is as below: 我的登录操作方法如下:

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();

In the custom authentication class that I wrote, Authentication , I have a Login method that works fine, also FindByName method returns an app user. 在我编写的自定义身份验证类Authentication ,我有一个很好的Login方法, FindByName方法也返回了一个应用程序用户。 But if I try to SignIn with that login, the user isn't recognized as authenticated and HttpContext.User.Identity is always null, so I imagine that I have to try UserManager.FindAsync . 但是,如果我尝试SignIn与登录时,用户不会被识别为认证和HttpContext.User.Identity总是空的,所以我想象我必须尝试UserManager.FindAsync

This method calls FindByNameAsync and GetPasswordHashAsync , and it always return null. 此方法调用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);
}

And the Authentication.FindByName 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;
}

As you can see I'm using database users, I'm not sure how I can retrieve a hashed password for them. 如您所见,我正在使用数据库用户,但不确定如何为他们检索哈希密码。 For now, I'm just storing the Base65 of the correct password! 现在,我只是存储正确密码的Base65!

I have no idea where I'm going wrong, any guidance is welcome. 我不知道我要去哪里错,欢迎任何指导。

Short answer: nothing's wrong. 简短的答案:没错。 User is authenticated in other action methods, but apparently not in the current action method. 通过其他操作方法对用户进行身份验证,但显然无法通过当前操作方法进行身份验证。

This is the process that I followed, maybe it will help you debug your app. 这是我遵循的过程,可能会帮助您调试应用程序。

After reading the source code , FindAsync first calls FindByNameAsync , followed by CheckPasswordAsync which references VerifyPasswordAsync . 读取源代码后FindAsync首先调用FindByNameAsync ,然后调用CheckPasswordAsync ,后者引用VerifyPasswordAsync So it should be fine If I could override VerifyPasswordAsync . 因此,如果我可以覆盖VerifyPasswordAsync那就应该VerifyPasswordAsync

I created a custom password hasher that implements IPasswordHasher , and registered it in the create method of my UserManager like this: 我创建了一个实现IPasswordHasher的自定义password hasher IPasswordHasher ,并将其注册到UserManagercreate方法中,如下所示:

manager.PasswordHasher = new DbPasswordHasher();

So by now, I can get my user from UserManager.FindAsync , but it turned out that it doesn't matter where you get the user since HttpContext.User.Identity is still null! 因此,到目前为止,我可以从UserManager.FindAsync获取用户,但是事实证明,由于HttpContext.User.Identity仍然为null,您在哪里获取用户都没有关系! My mistake was that I didn't notice the user isn't authenticated in the current action, in other action methods it works as expected! 我的错误是我没有注意到用户在当前操作中未通过身份验证,在其他操作方法中未按预期工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM