Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Add password to local account linked to external login

Suggested Videos
Part 119 - ASP.NET Core custom token provider | Text | Slides
Part 120 - ASP.NET Core encryption and decryption example | Text | Slides
Part 121 - Change password in asp.net core | Text | Slides

In this video we will discuss how to set password on a local user account that is linked to an external login like Google, Facebook etc. This allows the user to login using either the local user account or an external login.

Let us understand this with an example. If an external login provider like Google or Facebook is used to login, the Password column will be null for the corresponding local user account in AspNetUsers table. A local user account is usually linked to an external login using the email address.


It is possible to add a password for the local account that is linked to an external account. The obvious benefit of this is that, the user can use either the external login or the local account to login.


Add password to a local account

To add a password to a local user account that is linked to an external login, use AddPasswordAsync() method of the UserManager service.

userManager.AddPasswordAsync(user, model.NewPassword);

We pass 2 parameters to this method
  • The user object for whom we want to add the password
  • The new password
UserManager AddPasswordAsync example

Consider the following local user account in AspNetUsers table

add password to local account linked to external login

This local account is linked to my external Google login. So the PasswordHash column is NULL. We want to set password on the local user account, so we can either use local username and password or the google account to login. The following is the view that can be used to set the password.

asp.net core usermanager addpassword example

Add Password View Model

public class AddPasswordViewModel
{
    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPassword { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm new password")]
    [Compare("NewPassword", ErrorMessage = 
        "The new password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

Add Password View

@model AddPasswordViewModel

<h2>Add Password</h2>
<hr />
<p class="text-info">
    You have used an external account to login and do not have a local username and
    password. Simply set a new password if you want to login using a local account.
    Use your email as the username.
</p>
<div class="row">
    <div class="col-md-12">
        <form method="post">
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="NewPassword"></label>
                <input asp-for="NewPassword" class="form-control" />
                <span asp-validation-for="NewPassword" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ConfirmPassword"></label>
                <input asp-for="ConfirmPassword" class="form-control" />
                <span asp-validation-for="ConfirmPassword" class="text-danger">
                </span>
            </div>
            <button type="submit" class="btn btn-primary"
                    style="width:auto">
                Set Password
            </button>
        </form>
    </div>

</div>

Add Password Confirmation View

<h3>You have successfully set a local password. You can now use either 
    your local user account or an external account to login</h3>

AddPassword Actions

[HttpGet]
public async Task<IActionResult> AddPassword()
{
    var user = await userManager.GetUserAsync(User);

    var userHasPassword = await userManager.HasPasswordAsync(user);

    if (userHasPassword)
    {
        return RedirectToAction("ChangePassword");
    }

    return View();
}

[HttpPost]
public async Task<IActionResult> AddPassword(AddPasswordViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = await userManager.GetUserAsync(User);

        var result = await userManager.AddPasswordAsync(user, model.NewPassword);

        if (!result.Succeeded)
        {
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
            return View();
        }

        await signInManager.RefreshSignInAsync(user);

        return View("AddPasswordConfirmation");
    }

    return View(model);
}

Modify the code in HttpGet ChangePassword() action to redirect the user to AddPassword() action if the user has singed in using an external login account and tries to change password.

[HttpGet]
public async Task<IActionResult> ChangePassword()
{
    var user = await userManager.GetUserAsync(User);

    var userHasPassword = await userManager.HasPasswordAsync(user);

    if (!userHasPassword)
    {
        return RedirectToAction("AddPassword");
    }

    return View();
}

asp.net core tutorial for beginners

No comments:

Post a Comment

It would be great if you can help share these free resources