首页 > 解决方案 > 退出后无法重新登录

问题描述

使用 Visual Studio 2019、asp.net core 2.2 和 razor pages,我使用 Visual Studio 的功能添加“新的脚手架项目”,然后选择“身份”,然后我选择了帐户登录、帐户注销、忘记密码、拒绝访问,注册,重置密码选项。我添加了一个新的布局页面来与这些脚手架页面一起使用,这样我就可以控制它的样式和布局。登录,注册和更改密码都可以工作。问题是,一旦用户注销,他们就无法再次登录,登录的唯一方法是重置密码。这很奇怪,因为在 razor 页面操作的后端,我没有修改任何脚手架代码。

我尝试输入浏览器路由 /Account/Logout 以确保它正确注销。我在 Login 操作上使用了调试器,我可以看到该帐户没有被锁定。我没有启用两个因素,所以这不应该是问题。即使我 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);

    }

在此处输入图像描述

登录管理器没有给出错误消息,但我可以通过调试器看到登录管理器无法对用户进行身份验证。如果我重置密码,登录管理器将成功。然后,在我明确注销后,相同的密码不再有效,我必须再次重置才能再次成功进行身份验证。

标签: asp.net-corerazor-pagesasp.net-identity-2

解决方案


在 signInManager 行下断点,发现结果是NotAllowed."Not Allowed" 是有道理的,但是没有返回错误消息——所以这不是了解发生了什么的最好方法。幸运的是,.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.EmailConfirmed在Register方法中设置为true,如下所示:

var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
user.EmailConfirmed = true;
var result = await _userManager.CreateAsync(user, Input.Password);

推荐阅读