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))
你知道我的代码在执行中阻塞的原因吗?
这里的问题是这一行:
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.
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |