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);
Related
In a Web API project I am using the following method to sign in my user but at a latter point I want to get my user first name and last name. I am using Web API and .NET 5.
public AuthenticateResponse Authenticate(AuthenticateRequest model, string ipAddress)
{
var user = _userManager.Users
.Where(w => w.UserName == model.Username)
.FirstOrDefault();
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set
lockoutOnFailure: true
var result = _signInManager.PasswordSignInAsync(model.Username, model.Password, true, lockoutOnFailure: false);
User users = new User();
users.Username = model.Username;
users.Password = model.Password;
users.FirstName = user.FirstName;
users.LastName = user.LastName;
if (result.Result.Succeeded)
{
// return null if user not found
if (user == null)
return null;
}
// authentication successful so generate jwt and refresh tokens
var jwtToken = generateJwtToken(users);
var refreshToken = generateRefreshToken(ipAddress);
// save refresh token
// users.RefreshTokens.Add(refreshToken);
return new AuthenticateResponse(users, jwtToken, null);
}
I have this method in a UserService class how would one best access the values from
users.FirstName
users.LastName
from the Web API controller which could be say clubs. As you see I am using the signin manager and usermanager should I simply load an instance of that in my ClubController.
My API method is
[HttpPost]
[Route("Clubs/Create")]
public async Task<IActionResult> Create(ClubViewModelApi clubModel)
{
if (ModelState.IsValid)
{
Club _club = new Club();
_club.Name = clubModel.Name;
_club.Description = clubModel.Description;
_club.isActive = clubModel.isActive;
_club.isDeleted = clubModel.isDeleted;
_club.CreatedDate = DateTime.Now;
_club.CreatedBy = insert first lastname here;
_club.CreatedBy = User.Identity.
_context.Clubs.Add(_club);
await _context.SaveChangesAsync();
return Ok();
}
return View(clubModel);
}
I wish to insert the first name and last name here _club.CreatedBy at this point of the above api end point.
I create my token with this code when I authenticate:
private string generateJwtToken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var secret = _configRoot.GetValue<string>("JWTSecret");
_logger.Log(LogLevel.Information, $"JWT Secret from Everleap={secret}");
var key = Encoding.ASCII.GetBytes(secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddMinutes(15),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
My details are stored in a jwttoken. Do I go out to that token again and decrypt it on the controller level.
Response body
{
"id": 0,
"firstName": "david",
"lastName": "buckley",
"username": "davidbuckleyweb#outlook.com",
"jwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjAiLCJuYmYiOjE2MTY0MzAzNzUsImV4cCI6MTYxNjQzMTI3NSwiaWF0IjoxNjE2NDMwMzc1fQ.P8smaC0PAB5uSrBbI8bbHoc2PKbwIj7mI0jLnBuJz4s",
"refreshToken": null
}
I figured out that what I need to do is extend my claims so that its stored in the token it self I use the following to encode the token
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("CreatedBy", user.FirstName.Substring(0,1).ToUpper() + " " + user.LastName.Substring(0,1).ToUpper()),
new Claim(ClaimTypes.Email, user.Username),
new Claim(ClaimTypes.Name, user.FirstName + " " + user.LastName),
new Claim(ClaimTypes.Role,roles)
}),
Expires = DateTime.UtcNow.AddMinutes(15),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
Then to decode it I use the following.
var authorization = Request.Headers[HeaderNames.Authorization];
if (AuthenticationHeaderValue.TryParse(authorization, out var headerValue))
{
// we have a valid AuthenticationHeaderValue that has the following details:
var scheme = headerValue.Scheme;
var JWTToken = headerValue.Parameter;
var token = new JwtSecurityToken(jwtEncodedString: JWTToken);
string name = token.Claims.First(c => c.Type == "CreatedBy").Value;
_club.CreatedBy = name;
}
I am using Asp.net core for develop web application with google Authentication Login
I succeed to manage up to get google credential and register the User at very first. But the problems is even user register to the Application with Google Credentials,it always ask for register again and again for the application.
I found that it happen due to ExternalLoginSignInAsync function calling and it always give false for that ,I changed these parameters and tried several times
isPersistent:false/true) and bypassTwoFactor : true/false I have test above all variations. But it always give false for result .As well as I tried with Google Authentication with Normally Registered User login.it also gave me same result
public async Task<IActionResult> OnGetCallbackAsync(string returnUrl =null,string remoteError = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (remoteError != null)
{
ErrorMessage = $"Error from external provider:
{remoteError}";
return RedirectToPage("./Login", new {ReturnUrl = returnUrl });
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information.";
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}
var result = await
_signInManager.ExternalLoginSignInAsync(info.LoginProvider,
info.ProviderKey, isPersistent:false, bypassTwoFactor : true);
if (result.Succeeded)
{
_logger.LogInformation("{Name} logged in with {LoginProvider}
provider.", info.Principal.Identity.Name,
info.LoginProvider);
// return LocalRedirect(returnUrl);
return LocalRedirect("/Customer/ProjectsApiKey/");
}
Could you please any anyone who has already resolved this this problems help me to.I am expecting what should I do for check user already registered or not with Google Authentication
When GetExternalLoginInfoAsync returns false you can check user exists, if the user exists then add login.
Otherwise, the user does not have an account, then asks the user to create an account.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
return RedirectToAction("Index", "Home");
}
if (result.IsLockedOut)
{
return RedirectToAction(nameof(Lockout));
}
else
{
var user = await _userManager.FindByEmailAsync(email);
if (user != null)
{
var resultTemp = await _userManager.AddLoginAsync(user, info);
if (resultTemp.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: true);
return RedirectToAction("Index", "Home");
}
}
// User does not have an account, then ask the user to create an account.
ViewData["ReturnUrl"] = returnUrl;
ViewData["LoginProvider"] = info.LoginProvider;
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
}
I found the fault finally , it happened due to Email Confirmation thing,In my startup.cs class I have added the
config.SignIn.RequireConfirmedEmail = true;
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(config =>
{
config.SignIn.RequireConfirmedEmail = true;
})
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
// requires
// using Microsoft.AspNetCore.Identity.UI.Services;
// using WebPWrecover.Services;
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
due to this it always required to confirm the user Login email even we use Google Authentication.In order to fix this what I have did was when I create new user using Google Authentication login I set user parameters including EmailConfirmation=true addition to User name & User Email.Then that bug was fixed. after that when I call below function
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
public async Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
// Get the information about the user from the external login provider
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information during confirmation.";
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}
if (ModelState.IsValid)
{
// var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; comment dulith
var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email ,EmailConfirmed=true};
var result = await _userManager.CreateAsync(user);
await _userManager.AddToRoleAsync(user, SD.User);
if (result.Succeeded)
{
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
// return LocalRedirect(returnUrl);
return LocalRedirect("/Customer/ProjectsApiKey/");
}
}
If user Exists
result.Succeeded is true
And also Thank you very much for previous answer.
I'm modify my authentication from using Identity server to use the built in .net-core authentication. I'm trying to obtain the Access Tokens From An external Login. But when I go to obtain the User from the User Manager it returns null. I'm using the OAuth Authorization Code flow to login. I have a callback method which signs in and returns a JWT (I've omited some irrelevant code for simplicity)
[HttpGet("ExternalLoginCallback")]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
var info = await _signInManager.GetExternalLoginInfoAsync();
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
var user = await (result.Succeeded ?
_userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey)
: this.CreateIdentityUser(info));
var serviceProvider = HttpContext.RequestServices;
var context = serviceProvider.GetRequiredService<PublicAstootContext>();
await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
_logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider);
return await GenerateJwtResponse(_jwtFactory.GenerateClaimsIdentity(user.UserName, user.Id, userId),
_jwtFactory, _jwtOptions);
}
I create my User Identity like so:
private async Task<IdentityUser> CreateIdentityUser(ExternalLoginInfo info)
{
string email = await this.GetEmailFromLoginInfo(info);
//var email = info.Principal.FindFirstValue(ClaimTypes.Email);
var user = new IdentityUser { UserName = email, Email = email };
var signinResult = await _userManager.CreateAsync(user);
if (false == signinResult.Succeeded)
{
throw new Exception("Failed to Create User");
}
var addLoginResult = await _userManager.AddLoginAsync(user, info);
if (addLoginResult.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
}
return user;
}
When I go to obtain the Third Party Access Token
var user = httpContext.User;
var userManager = sp.GetRequiredService<UserManager<IdentityUser>>();
var userFromManager = userManager.GetUserAsync(user).Result;
var accessToken = userManager.GetAuthenticationTokenAsync(
userFromManager, "Coinbase", "access_token").Result;
EDIT
I cannot find my User in the the UserManager. How can I obtain my third party access token?
It looks like my HttpContext.User and my UserManager is out of sync.
var user = httpContext.User;
var userManager = sp.GetRequiredService<UserManager<IdentityUser>>();
if(false == user.TryGetClaimByType<string>(AuthenticationRule.EMAIL_CLAIM_TYPE, out var email))
{
throw new UnauthorizedAccessException();
}
How can I Sync the HttpContext.User and the Usermanger so I can simply call:
var userFromManager = userManager.GetUserAsync(user).Result;
I am trying to write code for email confirmation during email registration for my website. I have a bit customized User model which is similar to regular User code.
The code for sending the email confirmation is in within the Register action:
userService.InsertUser(user);
var appuser = new ApplicationUser(user); //{ UserName = model.Email, Email = model.Email };
appuser.UserName = model.Email;
//var result = await UserManager.CreateAsync(appuser, 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 http://go.microsoft.com/fwlink/?LinkID=320771
// // Send an email with this link
string code = await UserManager.GenerateEmailConfirmationTokenAsync(appuser.Id);
//string htmlcode = HttpUtility.UrlEncode(code);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = appuser.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(appuser.Id, "Confirm your account", "Please confirm your account by clicking here");
return RedirectToAction("RegisterComplete");
From the code, I got the callbackurl which is like http://localhost:63599/Account/ConfirmEmail?userId=22&code=C3mfUtYqGzVCsrCnE5VDzC0wfsbgP6lMSVgqFk25kym3uGh0%2B%2Bltqyh0VRim1ulbwSRHBzAgUCJ1WceipbRcErddmNJqzkksZN50QO%2FqTRprpgKcW19wX33QtftwCh7zUz%2B01aghCdg8jZ8Ff%2FNVfRvbjyIW0wavN0Ueq3xl6jBmrv%2BrnbtuKLJO%2BuFE2zHF
When I type the code into the browser, it will run the ConfirmEmail action from AccountController:
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
if (userId == null || code == null)
{
return View("Error");
}
var result = await UserManager.ConfirmEmailAsync(userId, code);
//if (result.Succeeded)
//{
// UserService userService = new UserService();
// long uid = long.Parse(userId);
// User user = userService.GetBy(u => u.UserID == uid).FirstOrDefault();
// user.IsVerified = true;
// userService.Update(user);
//}
return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
But the result.Succeeded is false. And result.Error[0] : Name cannot be null or empty.
I cannot find anymore information about this error in this context and therefore I am quite stuck.
If I change the confirmation code, I will get result.Error[0]: Invalid token, this made me think that at least my token has been correct. But I don't what this error is complaining about.
Any help/pointers will be appreciated.
I have a fairly standard implementation of Identity in my Core 2 application.
I have enabled the requirement for a confirmation email. This all works well - it generates and sends the email, with a valid link, which when clicks confirms the user's account. No problems there.
The situation is though, that if an email goes missing/is deleted/never arrives for whatever reason.
What I am doing, is using the standard login method, and if IsNotAllowed then I push them towards a page which tells them they need to activate their account, check their email etc.
On that page, I have a Form with a button which Posts to a controller to regenerate and resend the email.
I literally copy and pasted the code from the standard Register method into my custom method.
The problem is when clicking the link the Activation fails. I get an InvalidToken error.
Any ideas why and how to fix?
Login Method
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email,
model.Password, model.RememberMe, lockoutOnFailure : false);
if (result.IsNotAllowed)
{
var user = await _userManager.FindByEmailAsync(model.Email);
EmailConfirmationViewModel viewModel = new EmailConfirmationViewModel();
viewModel.Email = model.Email;
return RedirectToAction("AwaitingEmailConfirmation", viewModel);
}
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return RedirectToAction("Index", "Races");
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Register Method
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
FirstName = model.FirstName,
LastName = model.LastName,
MobileNumber = model.MobileNumber,
Marketing = model.Marketing,
Newsletter = model.Newsletter,
Source = "Website"
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
//await _createContact.CreateContactAsync(model.Email, model.FirstName,
//model.LastName, model.Marketing, model.Newsletter);
var fields = new Dictionary<string, string>();
fields.Add("firstname", model.FirstName);
fields.Add("lastname", model.LastName);
fields.Add("newsletter", model.Newsletter.ToString());
fields.Add("marketing", model.Marketing.ToString());
fields.Add("source", "Website");
string publicaccountid = "55ebcc8b-b23f-4843-9dcb-1df08811de65";
var createcontact = ElasticEmailClient.Api.Contact.AddAsync(publicAccountID: publicaccountid,
email : model.Email, field : fields, sendActivation : false);
//await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created a new account with password.");
EmailConfirmationViewModel viewModel = new EmailConfirmationViewModel();
viewModel.Email = user.Email;
return RedirectToAction("AwaitingEmailConfirmation", viewModel);
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
Resend Email Method
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> ResendConfirmationEmail(EmailConfirmationViewModel model)
{
var user = await _userManager.FindByEmailAsync(model.Email);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
return RedirectToAction("AwaitingEmailConfirmation", model);
}