0

For security, I don't want just anybody to be able to register on my site but I can't stop users from registering while there is a registration page accessible on the site, so I added an "Authorized" flag to the ApplicationUser model:

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool Authorized { get; set; }
}

The idea is that if a user, whether logged in or not, does not have the value for this property set to true, the user will not be able to access secured content. A previously authorized user will have to authorize new users.

This brings into question how to get the first user authorized so I figured I'd seed the user in on my Migration. See below:

namespace Ortund.Migrations
{
    internal sealed class Configuration :
        DbMigrationsConfiguration<Ortund.Models.ApplicationDbContext>
    {
        protected override void Seed(Ortund.Models.ApplicationDbContext context)
        {
            context.Users.AddOrUpdate(
                u => u.Id,
                new Models.ApplicationUser { EmailAddress = "email@site.com", Authorized = true, EmailConfirmed = true }
            );
        }
    }
}

Obviously I'm missing some crucial fields here Password hashes for one and that's where I'm having trouble.

I don't know how the UserManager hashes the password so I can't seem replicate that process here since the function is not an async Task.

For reference, here's the Register method in the AccountController:

public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
        var result = await UserManager.CreateAsync(user, model.Password);
        ...
    }
}

The CreateAsync function specifies a cleartext password string that will be hashed. Attempting to replicate this in my Seed method above, I only have access to ApplicationUserManager.Create(Microsoft.AspNet.Identity.Owin.IdentityFactorOptions<ApplicationUserManager> options, Microsoft.Owin.IOwinContext context) which as far as I can see, doesn't suit my requirement here.

How can I create a full ApplicationUser in my seeded data?

Ortund
  • 8,095
  • 18
  • 71
  • 139
  • Its been a long time since ive done this but m pretty sure you should be overriding the seed method on the DbContext as opposed to a migration. – Derek Mar 07 '17 at 09:46
  • 1
    An "Authorised" role would serve the same purpose, but would fit the existing security model (meaning you won't have to jump through hoops to restrict access to actions). Re: your current question, let the framework handle account setup for you. – Basic Mar 07 '17 at 09:58

1 Answers1

5

You could call in to the UserManager.Create method and pass it the username and plain text password. That will hash the password for you and get that into the database

Something like this:

var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
var user = new ApplicationUser { UserName = "username"};
userManager.Create(user, "password");
Jinish
  • 1,983
  • 1
  • 17
  • 22
  • ... And then set the `Authorised` flag. – Basic Mar 07 '17 at 09:56
  • I'm far from being able to debug this as I've got a lot of stuff still to do on the project, but there are no design time errors so I'm giving you an upvote on this answer – Ortund Mar 07 '17 at 10:24