PasswordSignInAsync()似乎在没有任何错误的情况下阻塞

Els*_*nia -1 c# asp.net-identity asp.net-core asp.net-core-identity

我正在尝试使用ASP.NET Core Identity 2.0在我现有的应用程序中设置身份验证.当我使用自己的数据库模式和类时,我有自己的User类,我不得不创建自定义UserStore和自定义UserManager.

所以我在AccountController中有我的登录功能:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, set lockoutOnFailure: true
            var result = await _signInManager.PasswordSignInAsync(model.Login, model.Password, model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation("User logged in.");
                return RedirectToLocal(returnUrl);
            }
            if (result.IsLockedOut)
            {
                _logger.LogWarning("User account locked out.");
                return RedirectToAction(nameof(Lockout));
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Connection failed.");
                return View(model);
            }
        }
        return View(model);
    }
Run Code Online (Sandbox Code Playgroud)

我有自定义UserManager:

public class CustomUserManager<TUser> : UserManager<TUser> where TUser : User
{
public CustomUserManager(IUserStore<TUser> store, IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<TUser> passwordHasher, IEnumerable<IUserValidator<TUser>> userValidators,
IEnumerable<IPasswordValidator<TUser>> passwordValidators, ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<TUser>> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
{
}

public override Task<bool> CheckPasswordAsync(TUser user, string password)
{
    bool passwordIsSimilar = password == user.Password;

    return new Task<bool>(() => passwordIsSimilar);
}
}
Run Code Online (Sandbox Code Playgroud)

我的服务声明:

        services.AddIdentity<User, ProfileUser>().AddUserManager<CustomUserManager<User>>().AddDefaultTokenProviders();
        services.AddTransient<IUserStore<User>, UserIdentity>();
        services.AddTransient<IRoleStore<ProfileUser>, ProfileIdentity>();

        services.Configure<IdentityOptions>(options =>
        {
            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 10;
            options.Lockout.AllowedForNewUsers = true;
        });

        services.ConfigureApplicationCookie(options =>
        {
            // Cookie settings
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
            // If the LoginPath isn't set, ASP.NET Core defaults 
            // the path to /Account/Login.
            options.LoginPath = "/Account/Login";
            // If the AccessDeniedPath isn't set, ASP.NET Core defaults 
            // the path to /Account/AccessDenied.
            options.AccessDeniedPath = "/Account/AccessDenied";
            options.SlidingExpiration = true;
        });
Run Code Online (Sandbox Code Playgroud)

我的自定义UserManager工作,并在用户登录时调用CheckPasswordAsync().但是,此后,函数等待_signInManager.PasswordSignInAsync(model.Login,model.Password,model.RememberMe,lockoutOnFailure:false); 似乎在某处阻止.调试模式没有错误,执行没有传递到下一行(if(result.Succeeded))

你知道我的代码在执行中阻塞的原因吗?

Kir*_*kin 6

这里的问题是这一行:

return new Task<bool>(() => passwordIsSimilar);
Run Code Online (Sandbox Code Playgroud)

该Task 构造并不实际运行的任务; 它只是初始化它.调用的代码CheckPasswordAsync正在等待此任务完成,但由于它从未启动过,所以不会发生这种情况.

正如Stephen Cleary 写道:不要使用Task或Task<T>构造者.相反,在您的示例中,您可以简单地使用Task.FromResult<T>,如下所示:

return Task.FromResult(passwordIsSimilar);
Run Code Online (Sandbox Code Playgroud)

从本质上讲,这会Task为您创建一个已经完成的新结果passwordIsSimilar.任何解开任务(通常使用await)的东西都将检索到的值passwordIsSimilar.