Cannot find User with ID '' after first access from Login to ChangePassword – Identity Asp net core

huangapple go评论73阅读模式
英文:

Cannot find User with ID '' after first access from Login to ChangePassword - Identity Asp net core

问题

I've customized the Identity AspNetUsers table by adding a custom field "IsChangedPassword" which, if is false, a user is forced to change the current temp password. In OnPostAsync of Login.cshtml.cs I've added these lines:

var result = await _signInManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
    if (!user.IsChangedPassword)
    {
        return RedirectToPage("./Manage/ChangePassword");
    }
    else
    {
        _logger.LogInformation("User logged in.");
        return LocalRedirect(returnUrl);
    }
}

So, after the first login of an existing user with IsChangedPassword false, nothing goes right:

Unable to load user with ID ''.

My IdentityUser class is:

[Table("AspNetUsers", Schema = "dbo")]
public class MyCustomUser : IdentityUser
{
    public bool IsChangedPassword { get; set; }
    public bool IsBlocked { get; set; }
}

And in Program.cs:

builder.Services.AddMvc();
builder.Services.AddIdentityCore<MyCustomUser>(options =>
{
    options.SignIn.RequireConfirmedAccount = false;
    // Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 6;
    // Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;
    // User settings.
    options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
    options.User.RequireUniqueEmail = true;
})
.AddRoles<MyCustomRoles>()
.AddSignInManager<SignInManager<MyCustomUser>>()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<MyDBIdentityContext>();

Why I cannot force users to correctly change the password at the first access? The user EXISTS; IsChangedPassword is false; I didn't change anything in ChangePassword.cshtml.cs.

Thank you in advance.

英文:

I've customized the Identity AspNetUsers table by adding a custom field "IsChangedPassword" which, if is false, a user is forced to change the current temp password. In OnPostAsync of Login.cshtml.cs I'v added this lines:

var result = await _signInManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe, lockoutOnFailure: false);
                if (result.Succeeded)
                {
                    if (!user.IsChangedPassword)
                    {
                        return RedirectToPage(&quot;./Manage/ChangePassword&quot;);
                    }
                    else
                    {
                        _logger.LogInformation(&quot;User logged in.&quot;);
                        return LocalRedirect(returnUrl);
                    }
                }

So, after the first login od an existing user with IsChangedPassword false, nothing goes right:

Unable to load user with ID &#39;&#39;.

My IdentityUser class is:

[Table(&quot;AspNetUsers&quot;, Schema = &quot;dbo&quot;)]    
public class MyCustomUser : IdentityUser
{        
    public bool IsChangedPassword { get; set; }
    public bool IsBlocked { get; set; }
}

And in Program.cs:

	builder.Services.AddMvc();
		builder.Services.AddIdentityCore&lt;MyCustomUser&gt;(options =&gt;
{
	options.SignIn.RequireConfirmedAccount = false;
	// Password settings.
	options.Password.RequireDigit = true;
	options.Password.RequireLowercase = true;
	options.Password.RequireNonAlphanumeric = true;
	options.Password.RequireUppercase = true;
	options.Password.RequiredLength = 6;
	options.Password.RequiredUniqueChars = 6;
	options.Password.RequiredUniqueChars = 6;
	// Lockout settings.
	options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
	options.Lockout.MaxFailedAccessAttempts = 5;
	options.Lockout.AllowedForNewUsers = true;
	// User settings.
	options.User.AllowedUserNameCharacters = &quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_&quot;;
	options.User.RequireUniqueEmail = true;
})
.AddRoles&lt;MyCustomRoles&gt;()
.AddSignInManager&lt;SignInManager&lt;MyCustomUser&gt;&gt;()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores&lt;MyDBIdentityContext&gt;();

Why I cannot force to correctly change password at first access? The user EXISTS; IsChangedPassword is false; I didn't change anything in ChangePassword.cshtml.cs.

Thank you in advance.

答案1

得分: 0

我创建了一个示例,但您的问题似乎没有出现。您可以参考我下面的步骤。

右键单击项目 -> 添加 -> 新建受托项目项 -> Identity,然后选择相应的布局、要更改的页面、数据库上下文和模型:
Cannot find User with ID '' after first access from Login to ChangePassword – Identity Asp net core

安装Identity后,将自定义属性添加到 MyCustomUser 中:

public class MyCustomUser : IdentityUser
{
    public bool IsChangedPassword { get; set; }
    public bool IsBlocked { get; set; }
}

迁移并更新数据库:

Add-Migration CreateIdentitySchema
Update-Database

Layout.cshtml 中添加相应的部分视图,并在 Program.cs 中添加 RazorPage 中间件:

<partial name="_LoginPartial" />

app.MapRazorPages();

Login.cshtml.cs 中注入 UserManager,并在成功登录后添加判断条件:

public class LoginModel : PageModel
{
    private readonly SignInManager<MyCustomUser> _signInManager;
    private readonly UserManager<MyCustomUser> _userManager;
    private readonly ILogger<LoginModel> _logger;

    public LoginModel(SignInManager<MyCustomUser> signInManager, ILogger<LoginModel> logger, UserManager<MyCustomUser> userManager)
    {
        _signInManager = signInManager;
        _logger = logger;
        _userManager = userManager;
    }
    //...
    public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        //...
        var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
        if (result.Succeeded)
        {
            var user = await _userManager.FindByEmailAsync(Input.Email);
            if (!user.IsChangedPassword)
            {
                return RedirectToPage("./Manage/ChangePassword");
            }
            else
            {
                _logger.LogInformation("User logged in.");
                return LocalRedirect(returnUrl);
            }
        }
        //...
    }
}

然后在 ChangePassword.cshtml.cs 中,在成功更改密码后添加以下代码:

user.IsChangedPassword = true;
await _userManager.UpdateAsync(user);

您可以检查是否有任何步骤不正确。

英文:

I built an example, but your problem does not appear. You can refer to my steps below.

Right click on project -> Add -> New Scaffolded Item -> Identity, then select the corresponding layout, the page to be changed, the database context and the model:
Cannot find User with ID '' after first access from Login to ChangePassword – Identity Asp net core

After installing Identity, add your custom properties to MyCustomUser:

public class MyCustomUser : IdentityUser
{
    public bool IsChangedPassword { get; set; }
    public bool IsBlocked { get; set; }
}

Migrate and update the database:

Add-Migration CreateIdentitySchema
Update-Database

Add the corresponding partial view in Layout.cshtml, and add the RazorPage middleware in Program.cs:

&lt;partial name=&quot;_LoginPartial&quot; /&gt;

app.MapRazorPages();

Inject UserManager in Login.cshtml.cs and add judgment conditions after successful login:

public class LoginModel : PageModel
{
    private readonly SignInManager&lt;MyCustomUser&gt; _signInManager;
    private readonly UserManager&lt;MyCustomUser&gt; _userManager;
    private readonly ILogger&lt;LoginModel&gt; _logger;

    public LoginModel(SignInManager&lt;MyCustomUser&gt; signInManager, ILogger&lt;LoginModel&gt; logger, UserManager&lt;MyCustomUser&gt; userManager)
    {
        _signInManager = signInManager;
        _logger = logger;
        _userManager = userManager;
    }
    //...
    public async Task&lt;IActionResult&gt; OnPostAsync(string returnUrl = null)
    {
        //...
        var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
        if (result.Succeeded)
        {
            var user =await _userManager.FindByEmailAsync(Input.Email);
            if (!user.IsChangedPassword)
            {
                return RedirectToPage(&quot;./Manage/ChangePassword&quot;);
            }
            else
            {
                _logger.LogInformation(&quot;User logged in.&quot;);
                return LocalRedirect(returnUrl);
            }
        }
        //...
    }
}

Then in ChangePassword.cshtml.cs, add the following code after changing the password successfully:

user.IsChangedPassword = true;
await _userManager.UpdateAsync(user);

You can check if any of your steps is incorrect.

huangapple
  • 本文由 发表于 2023年7月20日 15:36:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727630.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定