Invalid Username or password on Seeded User Account MVC5 - entity-framework-6

I am working in a new MVC5 application that I built specifically to test this.
I have two db contexts. The configuration.cs for the ApplicationDbContext is as follows:
using FB.DOMAIN.Authentication;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Data.Entity.Migrations;
namespace FB.DAL.Migrations.ApplicationDbContext
{
internal sealed class Configuration : DbMigrationsConfiguration<DataContexts.ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
MigrationsDirectory = #"Migrations\ApplicationDbContext";
}
protected override void Seed(DataContexts.ApplicationDbContext context)
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
if (!roleManager.RoleExists("Admin"))
{
roleManager.Create(new IdentityRole("Admin"));
}
var user = new ApplicationUser { UserName = "james#world.com" };
if (userManager.FindByName("james#world.com") != null) return;
var result = userManager.Create(user, "Password123!");
if (result.Succeeded)
{
userManager.AddToRole(user.Id, "Admin");
}
}
}
}
Shouldn't the above code seed my database with a user? Sadly it doesn't! When I query the AspNetUsers table, it is blank!
What am I doing wrong? :(

I couldn't get two separate contexts talking. So I followed LukeP's solution here.
A single context that houses all my related domain logic.

Related

My seeder in the Migration Configuration class locks the application (Asp.net MVC)

I have the following Migration configuration class:
namespace MVC_Authentication.Migrations
{
using Microsoft.AspNet.Identity.EntityFramework;
using MVC_Authentication.Models;
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Threading.Tasks;
internal sealed class MigrationConfiguration : DbMigrationsConfiguration<ApplicationDbContext>
{
public MigrationConfiguration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "MVC_Authentication.Models.ApplicationDbContext";
}
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
SeedDatabase(context).GetAwaiter().GetResult();
}
protected async Task SeedDatabase(ApplicationDbContext ctx)
{
var roleManager = new ApplicationRoleManager(new RoleStore<IdentityRole>(ctx));
if (await roleManager.FindByNameAsync("Administrator") == null)
await roleManager.CreateAsync(new IdentityRole("Administrator"));
if (await roleManager.FindByNameAsync("User") == null)
await roleManager.CreateAsync(new IdentityRole("User"));
ApplicationUserManager userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(ctx));
var user_Admin = new ApplicationUser()
{
SecurityStamp = Guid.NewGuid().ToString(),
UserName = "Admin",
Email = "myEmail",
EmailConfirmed = true
};
if (await userManager.FindByNameAsync(user_Admin.UserName) == null)
{
await userManager.CreateAsync(user_Admin, "MyPassword");
await userManager.AddToRoleAsync(user_Admin.Id, "User");
await userManager.AddToRoleAsync(user_Admin.Id, "Administrator");
}
}
}
}
but when the execution arrives at:
if (await roleManager.FindByNameAsync("Administrator") == null)
the application locks and I can wait and wait.
Maybe I should not use RoleManager and UserManager here? It's the only way to seed roles and users.
Thanks for any hint of what possible can go wrong.
Try the synchronous method in RoleManager instead of in ApplicationRoleManager;
var roleStore = new RoleStore<IdentityRole>(db);
var roleManager = new RoleManager<IdentityRole>(roleStore);
roleManager.FindName(...);

I am trying to seed users and user roles in asp.net but only the roles succeed

Hey This is probably a newbie question but I honestly can't find the problem after hours of searching for answers.
I am trying to create two roles and an admin user by seeding the database. I get no compilation errors but after running the application I couldn't login so I checked the database and noticed that the roles were created successfully but not the admin user.
Here is the class that I use for seeding:
public class Initialize
{
public static async Task InitializeAsync(ApplicationDbContext context, IServiceProvider serviceProvider)
{
var RoleManager = serviceProvider.GetRequiredService < RoleManager<IdentityRole>>();
UserManager<ApplicationUser> userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
string[] rolenames = { "Admin","Member"};
IdentityResult roleResult;
foreach (var roleName in rolenames) {
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (!roleExist)
{
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
string username = "admin";
string email = "admin#example.com";
string password = "Secret123";
string role = "Admin";
if (await userManager.FindByEmailAsync(username) == null)
{
ApplicationUser user = new ApplicationUser
{
UserName = username,
Email = email
};
IdentityResult result = await userManager
.CreateAsync(user, password);
if (result.Succeeded)
{
await userManager.AddToRoleAsync(user, role);
}
}
}
}
My ConfigureServices :
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc();
}
And Here is my Program.cs :
public class Program
{
public static void Main(string[] args)
{
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<ApplicationDbContext>();
Initialize.InitializeAsync(context, services).Wait();
}
catch(Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "Error seeding");
}
}
host.Run();
}
Any help is appreciated :)
Try look at userManager -> Store -> Users -> Results Views -> Message after access via serviceProvider.GetRequiredService. You can have some error message about it here.
If it contains a message:
"Cannot create a DbSet for 'ApplicationUser' because this type is not
included in the model for the context."
you must changed ApplicationContext class inherit from IdentityDbContext and it should be works fine.

Checking User Roles to Display

I recently added Identity to my ASP.NET project, but I'm having trouble checking user roles.
I originally create my Admin role in Startup.cs:
private void createRolesandUsers()
{
ApplicationDbContext context = new ApplicationDbContext();
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
if (!roleManager.RoleExists("Admin"))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "Admin";
roleManager.Create(role);
var user = new ApplicationUser();
user.UserName = "admin";
user.Email = "admin#tpms.com";
string userPWD = "********";
var chkUser = UserManager.Create(user, userPWD);
if (chkUser.Succeeded)
{
var result1 = UserManager.AddToRole(user.Id, "Admin");
}
}
}
In my UserController.cs, I have a function to check if the user is an admin:
public Boolean isAdminUser()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var s = UserManager.GetRoles(user.GetUserId());
if (s[0].ToString() == "Admin")
{
return true;
}
else
{
return false;
}
}
return false;
}
However, I can't seem to find a way to access the isAdminUser() function from both my Views and my Controllers.
I've done a little bit of research the IsUserInRole() function, but when I tried:
#if (Roles.IsUserInRole(User.Identity.Name, "Admin")) { Html.ActionLink("Edit", "Edit", new { id=item.GuestID }); }
The if statement always returns false.
Try to use HttpContext.Current.User.IsInRole("Admin"); as Roles.IsUserInRole related to old membership provider under System.Web.Security namespace and need roleManager provider configuration in web.config.
#if(HttpContext.Current.User.IsInRole("Admin"))
{
Html.ActionLink("Edit", "Edit", new { id = item.GuestID });
}
Another way is to use UserManager
userManager.IsInRole("userId","Admin")

Asp.Net core MVC6 How to initially add roles in Identity 3

I've looked for this in Stackoverflow and so far it appears there are plenty of questions on adding roles in Identity 1 & 2 but its different in Identity 3.
I want to seed roles in the database. I have just two. I intended to use _roleManager which I have injected into the class. Thats fine. My problem is.. there doesnt appear to be any method to actually add a role.. Using CreateAsync is for adding the user to the role.. how do you code to add a role using "_userManager" or do you have to do it another way?
EDIT
Identity
In Identity RoleManager is for creating roles and UserManager is for adding users to roles.
This is an example to point you in the right direction. The code below is for creating a new role Administrator
if (!roleManager.RoleExists("Administrator"))
{
MyIdentityRole newRole = new MyIdentityRole("Administrator", "Administrators can do something with data");
roleManager.Create(newRole);
}
EDIT
Further, this is for adding a user to a role and this also an example:
\\assuming you test if the user has been assigned to the role "Administrator" before adding them to that role
if(RoleAdministrator == true){
userManager.AddToRole(User.Id, "Administrator");
}
public class SeedData
{
private const string _adminRoleName = "admin";
private string _adminEmail = "admin#demo.com";
private string _adminPassword = "P#ssw0rd!PK";
private string[] _roles = new string[] { _adminRoleName, "supervisor" };
private readonly RoleManager<IdentityRole<Guid>> _roleManager;
private readonly UserManager<ApplicationUser> _userManager;
public static async Task Run(IServiceProvider serviceProvider)
{
using (var serviceScope =serviceProvider
.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
var instance = serviceScope.ServiceProvider.GetService<SeedData>();
await instance.Initialize();
var context = serviceScope.ServiceProvider.GetService<AppDbContext>();
if (!context.Products.Any())
{
// Seed Other entities Here
}
await context.SaveChangesAsync();
}
}
public SeedData(UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole<Guid>> roleManager)
{
_roleManager = roleManager;
_userManager = userManager;
}
public async Task Initialize()
{
foreach (var role in _roles)
{
if (!await _roleManager.RoleExistsAsync(role))
{
await _roleManager.CreateAsync(new IdentityRole<Guid>(role));
}
}
var adminUsers = await _userManager.GetUsersInRoleAsync(_adminRoleName);
if (!adminUsers.Any())
{
var adminUser = new ApplicationUser()
{
Id = Guid.NewGuid(),
Email = _adminEmail,
UserName = _adminEmail
};
var result = await _userManager.CreateAsync(adminUser, _adminPassword);
if(result.Success)
{
await _userManager.AddToRoleAsync(adminUser, _adminRoleName);
}
}
}
}
In your Program.cs
public static void Main(string[] args)
{
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
SeedData.Run(services).Wait();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "Error while seeding database.");
}
}
host.Run();
}
Might be helpful to someone :)

MVC 5 Seed Users and Roles

I have been playing about with the new MVC 5, I have a few models, controller and views setup using code first migrations.
My question is how do I seed users and roles? I currently seed some reference data in my Seed method in Configuration.cs. But it looks to me that the user and roles tables are not created until something first hits the AccountController.
I currently have two connection strings so I can separate my data from my authentication into different databases.
How can I get the user, roles, etc tables populate along with my others? And not when the account controller is hit?
Here is example of usual Seed approach:
protected override void Seed(SecurityModule.DataContexts.IdentityDb context)
{
if (!context.Roles.Any(r => r.Name == "AppAdmin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "AppAdmin" };
manager.Create(role);
}
if (!context.Users.Any(u => u.UserName == "founder"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser {UserName = "founder"};
manager.Create(user, "ChangeItAsap!");
manager.AddToRole(user.Id, "AppAdmin");
}
}
I used package-manager "update-database". DB and all tables were created and seeded with data.
It's a small addition, but to anyone having the "UserId not found." message when trying to seed: (Tom Regan had this question in the comments, and I was stuck on it myself for a while)
This means that the manager.Create(user, "ChangeItAsap!") was not successful.
This might have a different reason, but for me it was because my password was not succeeding its validation.
I had a custom passwordvalidator, which was not being called when seeding the database, so the validation rules i was used to (minlength 4 instead of default 6) did not apply. Make sure your password (and all other fields for that matter) is passing validation.
This is my method base on Valin answer, I have added roles in db and added password for user. This code is placed in Seed() method in Migrations>Configurations.cs.
// role (Const.getRoles() return string[] whit all roles)
var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
for (int i = 0; i < Const.getRoles().Length; i++)
{
if (RoleManager.RoleExists(Const.getRoles()[i]) == false)
{
RoleManager.Create(new IdentityRole(Const.getRoles()[i]));
}
}
// user
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var PasswordHash = new PasswordHasher();
if (!context.Users.Any(u => u.UserName == "admin#admin.net"))
{
var user = new ApplicationUser
{
UserName = "admin#admin.net",
Email = "admin#admin.net",
PasswordHash = PasswordHash.HashPassword("123456")
};
UserManager.Create(user);
UserManager.AddToRole(user.Id, Const.getRoles()[0]);
}
Here i have an very easy,clean and smooth solution.
protected override void Seed(UserContext context)
{
//Step 1 Create the user.
var passwordHasher = new PasswordHasher();
var user = new IdentityUser("Administrator");
user.PasswordHash = passwordHasher.HashPassword("Admin12345");
user.SecurityStamp = Guid.NewGuid().ToString();
//Step 2 Create and add the new Role.
var roleToChoose = new IdentityRole("Admin");
context.Roles.Add(roleToChoose);
//Step 3 Create a role for a user
var role = new IdentityUserRole();
role.RoleId = roleToChoose.Id;
role.UserId = user.Id;
//Step 4 Add the role row and add the user to DB)
user.Roles.Add(role);
context.Users.Add(user);
}
protected override void Seed(ApplicationDbContext context)
{
SeedAsync(context).GetAwaiter().GetResult();
}
private async Task SeedAsync(ApplicationDbContext context)
{
var userManager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context));
var roleManager = new ApplicationRoleManager(new RoleStore<ApplicationRole, int, ApplicationUserRole>(context));
if (!roleManager.Roles.Any())
{
await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AdminRoleName });
await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AffiliateRoleName });
}
if (!userManager.Users.Any(u => u.UserName == "shimmy"))
{
var user = new ApplicationUser
{
UserName = "shimmy",
Email = "shimmy#gmail.com",
EmailConfirmed = true,
PhoneNumber = "0123456789",
PhoneNumberConfirmed = true
};
await userManager.CreateAsync(user, "****");
await userManager.AddToRoleAsync(user.Id, ApplicationRole.AdminRoleName);
}
}
Looks like they changes the way authentication works in MVC5, changed my Global.asax.cs to the following did the trick!
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Threading.Tasks;
using MvcAuth.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System.Threading;
using Microsoft.AspNet.Identity.EntityFramework;
namespace MvcAuth
{
public class MvcApplication : System.Web.HttpApplication
{
async Task<bool> AddRoleAndUser()
{
AuthenticationIdentityManager IdentityManager = new AuthenticationIdentityManager(
new IdentityStore(new ApplicationDbContext()));
var role = new Role("Role1");
IdentityResult result = await IdentityManager.Roles.CreateRoleAsync(role, CancellationToken.None);
if (result.Success == false)
return false;
var user = new ApplicationUser() { UserName = "user1" };
result = await IdentityManager.Users.CreateLocalUserAsync(user, "Password1");
if (result.Success == false)
return false;
result = await IdentityManager.Roles.AddUserToRoleAsync(user.Id, role.Id, CancellationToken.None);
return result.Success;
}
protected async void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
bool x = await AddRoleAndUser();
}
}
}
write this code in your Migration Configuration.
note: Use ApplicationDbContext in Configuration Class.
internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = false;
}
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
context.Roles.AddOrUpdate(p =>
p.Id,
new IdentityRole { Name = "Admins"},
new IdentityRole { Name = "PowerUsers" },
new IdentityRole { Name = "Users" },
new IdentityRole { Name = "Anonymous" }
);
}
}

Resources