why cant i create a new user in a mixed authentication project - c#

I am trying to create a user for a mixed authentication project. I am using MixedAuthExtension.cs.
I encounter a problem when I reach this line
IdentityResult result = await UserManager.CreateAsync(user,model.Password);
but the system user is created and the AspNetUser.
Thanks in advance for your help
The current code creates both the system user and ASP.NET user but it fails to sync identity
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<ActionResult> CreateSystemUser(RegisterViewModel model, string key)
{
var _context = new RequestToFillDbContext();
#region Initialise
Initialise(_context);
var password = SecurityHelper.GeneratePassword();
UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(_context);
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(store);
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager) { AllowOnlyAlphanumericUserNames = false };
model.Password = password;
model.ConfirmPassword = password;
ModelState.Clear();
#endregion
string serviveNumber = model.ServiceNumber;
if (!_context.SystemUsers.Any(s => s.EmailAddress == model.EmailAddress)
&& !_context.SystemUsers.Any(s => s.UserName == model.UserName))
{
if (ModelState.IsValid)
{
var emp = new RequestToFillApplicationHelper().GetEmployeeByServiceNumber(serviveNumber);
model.Designation = emp.Designation;
//TODO: Query Db for Id
//var identityManager = new IdentityManager();
var user = new ApplicationUser
{
UserName = model.UserName,
Email = model.EmailAddress,
EmailConfirmed = true,
SystemUser = new SystemUser()
{
FirstName = model.FirstName,
LastName = model.LastName,
UserName = model.UserName,
CompanyName = model.CompanyName,
Designation = model.Designation,
EmailAddress = model.EmailAddress,
IsTemporaryPassword = true,
//TempPasswordExpiryDateTime = DateTime.Now.AddHours(24),
SystemUserTypeId = model.SystemUserTypeId,
ServiceNumber = model.ServiceNumber,
IsActive = true,
IsDeleted = false,
IsLocked = false,
CreatedDateTime = DateTime.Now,
IsPasswordReset = false
}
};
//db.SaveChanges();
try
{
IdentityResult result = await UserManager.CreateAsync(user,model.Password);
//Assign user to role
I get a
"Property set method not found."Line 258
which is below
IdentityResult result = await UserManager.CreateAsync(user,model.Password);

Related

{"UserId not found."} when using manager.CreateIdentity

We've been running for ~4 months, and so far we haven't had any complaints. Today, we have somebody complain as creating an account isn't working for them. So I tried myself, and debugging I have indeed found an issue.
We're getting an error of
{"UserId not found."}
Which happens at this line
var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
I can not understand why when I try to create an account it works perfectly, but using their email / name it always spits out errors... makes no sense to my inexperienced brain?
Here is my full code
public bool CreateUser(string userName, string Email, string Password, string fName, string lName, string country, string ip)
{
try
{
// Default UserStore constructor uses the default connection string named: DefaultConnection
var userStore = new UserStore<IdentityUser>();
var manager = new UserManager<IdentityUser>(userStore);
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 1,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false
};
var user = new IdentityUser() { UserName = userName, Email = Email, EmailConfirmed = false };
IdentityResult result = manager.Create(user, Password);
Utilities u = new Utilities();
var usersID = user.Id;
//u.SendMailConfirmation(Email, usersID, fName);
userDetails(usersID, ip, fName, lName, country);
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { }, userIdentity);
return true;
}
catch (Exception ex)
{
return false;
}
}
And you are sure an user does not already exist with the same email?

Create user programmatically using C# ASP.NET MVC Identity

I'm trying to add a user programmatically to ASP.NET MVC Identity.
The error I'm encountering is: UserManager threw an exception of type 'System.NullReferenceException'
This function is called through a POST not originating from this site. It sits right below public async Task<ActionResult> Register(RegisterViewModel model) in the AccountController.
[AllowAnonymous]
public async Task<bool> GenerateUser(string email)
{
var user = new ApplicationUser { UserName = email, Email = email };
string password = System.Web.Security.Membership.GeneratePassword(12, 4);
var result = await UserManager.CreateAsync(user, password);
if (result.Succeeded)
{
// Omitted
}
else { AddErrors(result); }
return true;
}
I have also attempted to use the below code to perform the same action, but I get the error that special characters can't be in the UserName (I am using an email address), but this is definitely allowed as it's how all my users are created using public async Task<ActionResult> Register(RegisterViewModel model).
string password = System.Web.Security.Membership.GeneratePassword(12, 4);
var store = new Microsoft.AspNet.Identity.EntityFramework.UserStore<ApplicationUser>();
var manager = new ApplicationUserManager(store);
var user = new ApplicationUser() { Email = email, UserName = email };
var result = manager.Create(user, password);
The user object is the same as if I had filled a form to create a new user on the site (using public async Task<ActionResult> Register(RegisterViewModel model)), and the password is just a string, also the same.
public async Task<ActionResult> Register(RegisterViewModel model) is as per the scaffolded default but here it is below anyway for reference:
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
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);
if (result.Succeeded)
{
//await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here");
//return RedirectToAction("Index", "Home");
// TODO: Email Sent
return View("ConfirmationSent");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
Edit:
I call the function with:
var result = new AccountController().GenerateUser(model.emailAddress);
Edit2:
As asked for: This is the class definition for the ApplicationUserManager
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 8,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
The issue is with the UserManager, this solves the issue.
ApplicationDbContext context = new ApplicationDbContext();
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
string password = System.Web.Security.Membership.GeneratePassword(12, 4);
var user = new ApplicationUser();
user.Email = model.Email;
user.UserName = model.Email;
string userPWD = password;
var result = UserManager.Create(user, userPWD);

Add new user and role to asp.net identity sample?

I have installed asp.net identity sample https://www.nuget.org/packages/Microsoft.AspNet.Identity.Samples and trying to create a new role "SAdmin" with the user "Sadmin#example.com". The user is created but "Sadmin" gets the same role as "Admin"
I have modified IdentityConfig.cs to
//Create User=Admin#Admin.com with password=Admin#123456 in the Admin role
public static void InitializeIdentityForEF(ApplicationDbContext db) {
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
const string name = "admin#example.com";
const string password = "Admin#123456";
const string roleName = "Admin";
const string Sname = "Sadmin#example.com";
const string Spassword = "SAdmin#123456";
const string SroleName = "SAdmin";
//Create Super if it does not exist
var Srole = roleManager.FindByName(SroleName);
if (Srole == null)
{
Srole = new IdentityRole(roleName);
var roleresult = roleManager.Create(Srole);
}
var Suser = userManager.FindByName(Sname);
if (Suser == null)
{
Suser = new ApplicationUser { UserName = Sname, Email = Sname };
var result = userManager.Create(Suser, Spassword);
result = userManager.SetLockoutEnabled(Suser.Id, false);
}
// Add Suser to Role Admin if not already added
var SrolesForUser = userManager.GetRoles(Suser.Id);
if (!SrolesForUser.Contains(Srole.Name))
{
var result = userManager.AddToRole(Suser.Id, Srole.Name);
}
//Create Role Admin if it does not exist
var role = roleManager.FindByName(roleName);
if (role == null) {
role = new IdentityRole(roleName);
var roleresult = roleManager.Create(role);
}
var user = userManager.FindByName(name);
if (user == null) {
user = new ApplicationUser { UserName = name, Email = name };
var result = userManager.Create(user, password);
result = userManager.SetLockoutEnabled(user.Id, false);
}
// Add user admin to Role Admin if not already added
var rolesForUser = userManager.GetRoles(user.Id);
if (!rolesForUser.Contains(role.Name)) {
var result = userManager.AddToRole(user.Id, role.Name);
}
}
The problem is in the code... The following code block is responsible
if (Srole == null)
{
**Srole = new IdentityRole(roleName);**
var roleresult = roleManager.Create(Srole);
}
Change the highlighted line to
**Srole = new IdentityRole(SroleName);**
That should solve it

Salted Password Hashing not validating correctly

I am trying to implement some basic security for logins on a development website. I am using this code (C#) from https://crackstation.net/hashing-security.htm
For some reason it just doesn't work, the password hash generated is stored in my DB exactly as generated, it just doesn't seem to work when I try to validate a password against the hash using ValidatePassword(string password, string correctHash)
The ValidatePassword is supposed to generate the same hash, but it doesn't.
Does anybody have any experience using this code, or have any code that actually works? I have tried several now, including the one on the MSDN and none seem to fit the bill. It is suggested I shouldn't try to write my own code to achieve this.
Here is my code that calls the method, I have validated during debugging that the inputs are correct.
I have copied the code from the linked website into a static helper class which is called by my service methods below.
public ResultModel Register(string emailAddress, string password, string givenName, string familyName)
{
var _db = new EntityConnection();
if (_db.Users.Any(x => x.isDeleted == false && x.EmailAddress == emailAddress))
return new ResultModel() { success = false, message = "Email Address already registered, please attempt to Login" };
password = HashHelper.CreateHash(password);
var user = new User()
{
EmailAddress = emailAddress,
Password = password,
GivenName = givenName,
FamilyName = familyName,
DateAdded = DateTime.Now,
isDeleted = false,
isApproved = false
};
_db.Users.Add(user);
_db.SaveChanges();
var activationToken = new Token()
{
TokenType = "Account Activation",
User = user,
UserID = user.UserID,
DateAdded = DateTime.Now,
TokenCode = Guid.NewGuid().ToString()
};
_db.Tokens.Add(activationToken);
_db.SaveChanges();
return new ResultModel() { success = true, entity = user };
}
public ResultModel Login(string emailAddress, string password)
{
var _db = new EntityConnection();
var user = _db.Users.Where(x => x.isDeleted == false && x.EmailAddress == emailAddress);
if (!user.Any() || user.Count() > 1)
return new ResultModel() { success = false, message = "Credentials supplied do not match an Account, please try again." };
var existingHash = user.First().Password;
var result = HashHelper.ValidatePassword(password, existingHash);
if (result)
return new ResultModel() { success = true, entity = user.First() };
else
return new ResultModel() { success = false, message = "Credentials supplied do not match an Account, please try again." };
}

Task.WaitAny is hanging

For some reason my Task.WaitAny line is hanging and I have no idea why. I am trying to create new user in the problem line of code. Here is the code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditUser([Bind(Include = "UserID, Email, UserName, Roles, RoleID, RoleName")] ManagerUserViewModel model)
{
if (ModelState.IsValid)
{
using (var context = new ApplicationDbContext())
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
ApplicationUser user = new ApplicationUser();
user.Email = model.Email;
user.UserName = model.UserName;
if (model.UserID == null || model.UserID == "" || model.UserID == "0")
{
// Since it didn't have a UserID, we assume this is a new User
Task.WaitAny(manager.CreateAsync(user, "Changeitasap!2"));

Categories