使用Visual Studio 2019,asp.net core 2.2和剃须刀页面,我使用了Visual Studio的功能添加“新的脚手架项目”,然后选择“身份”,然后选择了帐户登录,帐户注销,忘记密码,访问被拒绝,注册,重置密码选项。我添加了一个新的“布局”页面以与这些脚手架页面一起使用,以便我可以控制其样式和布局。登录,注册和更改密码都可以。问题是,一旦用户注销,他们将无法再次登录,唯一的登录方法是重置密码。这很奇怪,因为在剃刀页面操作的后端,我没有修改任何脚手架的代码。
我尝试输入浏览器路由/ Account / Logout以确保其正确注销。我在“登录”操作中使用了调试器,并且可以看到该帐户未锁定。我没有启用两个因素,所以这应该不是问题。即使我100%确定密码正确,登录管理器也无法登录。
public void ConfigureServices(IServiceCollection services)
{
_sendGridApiKey = Configuration["AuthMessageSenderOptions:SendGridKey"];
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<MyAppDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<MyAppUser, IdentityRole>(config =>
{
config.User.RequireUniqueEmail = true;
})
.AddDefaultUI(UIFramework.Bootstrap4)
.AddRoleManager<RoleManager<IdentityRole>>()
.AddEntityFrameworkStores<MyAppDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredLength = 8;
options.User.RequireUniqueEmail = false;
options.SignIn.RequireConfirmedEmail = true;
});
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.AddMvc().AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/");
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
登录管理器没有给出错误消息,但是通过调试器可以看到登录管理器无法验证用户身份。如果重设密码,登录管理器将成功。然后,在我明确注销后,该密码不再起作用,必须再次重置以再次成功进行身份验证。
答案 0 :(得分:1)
在signInManager行处创建断点,并发现结果为NotAllowed
。“不允许”是有意义的,但是没有附带错误消息-因此,这不是最佳选择知道发生了什么的方式。幸运的是,.NET Core可以轻松地深入源代码。
NotAllowed仅在此处设置:
protected virtual async Task<SignInResult> PreSignInCheck(TUser user)
{
if (!await CanSignInAsync(user))
{
return SignInResult.NotAllowed;
}
if (await IsLockedOut(user))
{
return await LockedOut(user);
}
return null;
}
CanSignInAsync方法
public virtual async Task<bool> CanSignInAsync(TUser user)
{
if (Options.SignIn.RequireConfirmedEmail && !(await UserManager.IsEmailConfirmedAsync(user)))
{
Logger.LogWarning(0, "User {userId} cannot sign in without a confirmed email.", await UserManager.GetUserIdAsync(user));
return false;
}
if (Options.SignIn.RequireConfirmedPhoneNumber && !(await UserManager.IsPhoneNumberConfirmedAsync(user)))
{
Logger.LogWarning(1, "User {userId} cannot sign in without a confirmed phone number.", await UserManager.GetUserIdAsync(user));
return false;
}
return true;
}
然后是问题的原因在您的Startup.cs配置中
services.Configure<IdentityOptions>(options =>
{
...
options.SignIn.RequireConfirmedEmail = true;
...
}
您可以参考以下方法来解决
1.pop进入数据库并将您的用户设置为EmailConfirmed = true
2。在如下所示的Register方法中将EmailConfirmed
设置为true:
var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
user.EmailConfirmed = true;
var result = await _userManager.CreateAsync(user, Input.Password);