Password Recovery in ASP.NET MVC5 - c#

I am working in an ASP.NET MVC 5 application. Users are able to register and login without any issues. However, when one user forgets his/her password, the forgot password process (already in place) doesn't do anything! No emails are sent to the user with a click here to reset password link.
Currently my ForgotPassword action method looks like this:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
{
// Don't reveal that the user does not exist or is not confirmed
return View("ForgotPasswordConfirmation");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
I am guessing that is left to the developers to implement. I Googled around and found nothing that was straight forward.
What is the easiest way to allow this?

Forget password action to generate reset token:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
{
// Don't reveal that the user does not exist or is not confirmed
return View("ForgotPasswordConfirmation");
}
// 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.GeneratePasswordResetTokenAsync(user.Id);
var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking here");
return RedirectToAction("ForgotPasswordConfirmation", "Account");
}
// If we got this far, something failed, redisplay form
return View(model);
}
Reset password action to reset password based on generated token:
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
AddErrors(result);
return View();
}
Relevent view models:
public class ResetPasswordViewModel
{
public string Email { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public string Code { get; set; }
}
public class ForgotPasswordViewModel
{
public string Email { get; set; }
}
But you need to configure Email service before sending emails.
public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
return configSendGridasync(message);
}
private Task configSendGridasync(IdentityMessage message)
{
var myMessage = new SendGridMessage();
myMessage.AddTo(message.Destination);
myMessage.From = new System.Net.Mail.MailAddress(
"you#somewhere.com", "My name");
myMessage.Subject = message.Subject;
myMessage.Text = message.Body;
myMessage.Html = message.Body;
var credentials = new NetworkCredential("userName","Password");
// Create a Web transport for sending email.
var transportWeb = new Web(credentials);
// Send the email.
if (transportWeb != null)
{
return transportWeb.DeliverAsync(myMessage);
}
else
{
return Task.FromResult(0);
}
}
}
At the end you need to register this class Identity in your user manager configurator add following lines:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// some code here
manager.EmailService = new EmailService();
}
See Account Confirmation and Password Recovery with ASP.NET Identity (C#) as a step by step tutorial.

Related

how to pass a Model from a controller to another controller

I'm starter in .NET MVC. I want to pass a model from one controller to another controller, model contain a password. My first controller is auth method, in that I used Claims, but another controller is a vote method there I need to Post an ID, Password and Vote. Password I need in vote controller for voting confirmation in database.
My code:
My model:
public class LoginModel
{
public string IDNP { get; set; }
public string VnPassword { get; set;
}
My first controller:
public class AuthController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index(LoginModel model)
{
var data = new LoginData();
data.IDNP = model.IDNP;
data.VnPassword = model.VnPassword;
var response = await session.Login(data);
if (response.Status == true)
{
var authclaims = new List<Claim>()
{
new Claim(ClaimTypes.Name, data.IDNP),
};
var authIdentity = new ClaimsIdentity(authclaims, "User Identity");
var userPrincipal = new ClaimsPrincipal(new[] {authIdentity});
HttpContext.SignInAsync(userPrincipal);
return RedirectToAction("Index", "Vote",new{pass=data.VnPassword});
}
else
{
return View();
}
}
}
My second controller:
public class VoteController : Controller
{
private IVote connection;
public VoteController()
{
var bl = new BusinessManager();
connection = bl.GetVote();
}
[Authorize]
public IActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index(VoteModel vote)
{
var identity = (ClaimsIdentity)User.Identity;
var voteindex = new VoteData();
voteindex.IDNP = identity.Name;
voteindex.VnPassword = ;
voteindex.Party = vote.Party;
var response = await connection.Vote(voteindex);
if (response.Status == true)
return RedirectToAction("Index", "Home");
else
{
return RedirectToAction("Index", "Auth");
}
}
}
Actually, it's a bad idea to send Id and Password to another controller. It conflicts SRP rule.
You should have only one controller that gets and uses password.
However, if you want to use this action, you can use this

Use MVC AccountController to login in Android App

I'm working on a mobile application (in Android) which has to connect to an Azure database (this database is also used by the web version of the app). I succeeded to send POST/PUT/GET requests to the webservice API, using HttpURLConnection and now I'm trying to login in the app using the MVC AccountController.
Here is the MVC AccountController method I'm trying to call:
// POST: /Account/Login
[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.Succeeded)
{
_logger.LogInformation(1, "User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning(2, "User account locked out.");
return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Here is the LoginViewModel structure(first parameter of the Login method)
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
And here is what I've already tried, but I received: Bad request
public static String apiURL = "http://mysite/account/login";
public static String logIn() {
HttpURLConnection connection = null;
try {
URL url = new URL(apiURL);
JSONObject postDataParams = new JSONObject();
postDataParams.put("Email", "test#yahoo.com");
postDataParams.put("Password", "mypass");
postDataParams.put("RememberMe", true);
JSONObject finalJson = new JSONObject();
finalJson.put("model", postDataParams);
finalJson.put("returnUrl", "");
connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(15000);
connection.setConnectTimeout(15000);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/json");
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(finalJson.toString());
out.close();
System.out.println(finalJson.toString());
StringBuilder sb = new StringBuilder();
sb.append("");
int HttpResult = connection.getResponseCode();
if (HttpResult == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(
connection.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
System.out.println("" + sb.toString());
} else {
System.out.println(connection.getResponseMessage());
}
return sb.toString();
} catch (Exception e) {
return new String("Exception: " + e.getMessage());
} finally {
connection.disconnect();
}
}
Does anyone have an idea of what should I do? Thank you!
I finally came to a solution, someone told me that I should give up using the LoginViewModel which is also used by the web version of the app. So I wrote a new controller with a new Resource and it works:
Here is the Controller code:
public class AccountMobileController : Controller
{
private readonly ApplicationDbContext context;
private readonly IMapper mapper;
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
private readonly string _externalCookieScheme;
// POST api/mobilelogin
[AllowAnonymous]
[HttpPost("/api/mobilelogin")]
public async Task<IActionResult> Login([FromBody]LoginMobileResource model)
{
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.Succeeded)
{
var user = context.Users.SingleOrDefault(c => c.Email == model.Email);
/* _logger.LogInformation(1, "User logged in.");
return RedirectToLocal(returnUrl);*/
var modeltoreturn = new LoginMobileResource
{
Status = "Ok",
Email = user.Email,
Password= "",
RememberMe = model.RememberMe,
UserId = user.Id
};
return Ok(modeltoreturn);
}
else
{
var modeltoreturn = new LoginMobileResource
{
Status = "Wrong password",
Email = model.Email,
Password = "",
UserId = ""
};
return Ok(modeltoreturn);
}
}
// If we got this far, something failed, redisplay form
model.Status = "Non-existent account";
return Ok(model);
}
}
And here is my LoginMobileResource
public class LoginMobileResource
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
public String Status { get; set; }
public String UserId { get; set; }
}
The java code is the same, except that now I send only the postDataParams
out.write(postDataParams.toString());

I make a login page and I want to show user info name Address etc when I successfully login

This is controller code for Login,
This is User Login Controller code where I authenticating user Email ID and password when user login redirected to Home Controller where I want to show user info
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(UserLogin login, string ReturnUrl = ""){
string message = "";
using (LoginEntities dc = new LoginEntities()){
var v = dc.Users.Where(a => a.EmailID == login.EmailID).FirstOrDefault();
var n = dc.Users.Where(a => a.Password == login.Password).FirstOrDefault();
if (v != null || n != null ){
if (string.Compare(Crypto.Hash(login.Password), v.Password) == 0){
int timeout = login.RememberME ? 525600 : 20;
var ticket = new FormsAuthenticationTicket(login.EmailID,login.RememberME,timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = DateTime.Now.AddMinutes(timeout);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
if (Url.IsLocalUrl(ReturnUrl)){
return Redirect(ReturnUrl);
}
else{
return RedirectToAction("Index", "Home");
}
}
else{
message = "Invalid Credential Provided";
}
}
else {
message = "Invalid Credential Provided";
}
}
ViewBag.Message = message;
return View();
}
Home Controller and index action where I redirect when I login,
This is Home Controller Where I redirected After Logging successfully please some one give a code for home controller and index action where i can Get Id of user That login and and and tell me how to show that in view
public class HomeController : Controller{
LoginEntities db = new LoginEntities();
// GET: Home
[Authorize]
public ActionResult Index(){
if (Session.Contents.Count == 0){
RedirectToAction("Login", "User");
}
return View();
}
}
Updated my code below, This might or might not work coz its coded here manually not on actual VS :P
// /Controller/TestController.cs
namespace XXXX.Controllers
{
public class TestController : Controller
{
public ActionResult User()
{
String UserId = User.Identity.GetUserId().ToString();
ApplicationDbContext db = new ApplicationDbContext();
var rs = db.Users.Find(UserId);
var model = new UserViewModel
{
UserName = rs.UserName,
FirstName = rs.FirstName,
LastName = rs.LastName,
Email = rs.Email
};
db.Dispose();
return View(model);
}
}
}
// /Models/UserViewModel.cs
namespace XXXX.Models
{
public class UserViewModel
{
public string Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
// /Views/Test/User.cshtml
#model XXXX.Models.UsersCreateViewModel
<p>
#Html.Raw(Model.FirstName)
</p>
above is just a sample you can use the info further

Validate EMAIL in login- MVC

I am relatively new to MVC. Would like to know how to validate a user's email address during login. For example, users who have an email address ending in "gmail.com" must be directed to a different view and other users with a different email should be directed to a different view. How should I go about doing this? Any help will be appreciated
Below is the code for my AccountController:
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using _PosWorx.Models;
using System.Web.Security;
namespace _PosWorx.Controllers
{
[Authorize]
public class AccountController : Controller
{
PosworxDBEntities db = new PosworxDBEntities();
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToAction("Index", "Supports");
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
public ActionResult SignIn()
{
return View();
}
//
// GET: /Account/VerifyCode
[AllowAnonymous]
public async Task<ActionResult> VerifyCode(string provider, string returnUrl, bool rememberMe)
{
// Require that the user has already logged in via username/password or external login
if (!await SignInManager.HasBeenVerifiedAsync())
{
return View("Error");
}
return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
//
// POST: /Account/VerifyCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> VerifyCode(VerifyCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// The following code protects for brute force attacks against the two factor codes.
// If a user enters incorrect codes for a specified amount of time then the user account
// will be locked out for a specified amount of time.
// You can configure the account lockout settings in IdentityConfig
var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(model.ReturnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid code.");
return View(model);
}
}
//
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
return View();
}
//
// 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 http://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");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ConfirmEmail
[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);
return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
//
// GET: /Account/ForgotPassword
[AllowAnonymous]
public ActionResult ForgotPassword()
{
return View();
}
//
// POST: /Account/ForgotPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
{
// Don't reveal that the user does not exist or is not confirmed
return View("ForgotPasswordConfirmation");
}
// 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.GeneratePasswordResetTokenAsync(user.Id);
// var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking here");
// return RedirectToAction("ForgotPasswordConfirmation", "Account");
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ForgotPasswordConfirmation
[AllowAnonymous]
public ActionResult ForgotPasswordConfirmation()
{
return View();
}
//
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
//
// POST: /Account/ResetPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
AddErrors(result);
return View();
}
//
// GET: /Account/ResetPasswordConfirmation
[AllowAnonymous]
public ActionResult ResetPasswordConfirmation()
{
return View();
}
//
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
//
// GET: /Account/SendCode
[AllowAnonymous]
public async Task<ActionResult> SendCode(string returnUrl, bool rememberMe)
{
var userId = await SignInManager.GetVerifiedUserIdAsync();
if (userId == null)
{
return View("Error");
}
var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(userId);
var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
//
// POST: /Account/SendCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SendCode(SendCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View();
}
// Generate the token and send it
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
return View("Error");
}
return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
}
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
// Sign in the user with this external login provider if the user already has a login
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
case SignInStatus.Failure:
default:
// If the user does not have an account, then prompt the user to create an account
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
}
}
//
// POST: /Account/ExternalLoginConfirmation
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
if (User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Manage");
}
if (ModelState.IsValid)
{
// Get the information about the user from the external login provider
var info = await AuthenticationManager.GetExternalLoginInfoAsync();
if (info == null)
{
return View("ExternalLoginFailure");
}
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}
AddErrors(result);
}
ViewBag.ReturnUrl = returnUrl;
return View(model);
}
//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
//
// GET: /Account/ExternalLoginFailure
[AllowAnonymous]
public ActionResult ExternalLoginFailure()
{
return View();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_userManager != null)
{
_userManager.Dispose();
_userManager = null;
}
if (_signInManager != null)
{
_signInManager.Dispose();
_signInManager = null;
}
}
base.Dispose(disposing);
}
[HttpPost]
[Authorize]
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index");
}
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
internal class ChallengeResult : HttpUnauthorizedResult
{
public ChallengeResult(string provider, string redirectUri)
: this(provider, redirectUri, null)
{
}
public ChallengeResult(string provider, string redirectUri, string userId)
{
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
}
#endregion
}
}
Hi check this part regex part i didn't test it. But you go with similar approach
// Login Success Authenticate
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
{
// check this section
var isGmail = Regex.IsMatch(model.Email, #"^*#g(oogle)?mail\.com$");
if (isGmail)
{
return View("GmailViewCshtml", model);
}
else
{
return RedirectToLocal(returnUrl);
}**
}
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
if you like you can use:
if (model.Email.toLower().contains("#gmail.com"))
{
// do something
}
in this case if the user put the string "#gmail.com" in the middle of his email address will couze a small bug :)
or this long line right here is much better:
if (model.Email.toLower().LastIndexOf("#gmail.com") == (model.Email.Length - 11 /* the length of "#gmail.com" + 1 */ )
{
// do something
}
Try this
if (model.Email.ToLower().EndsWith("#gmail.com") && model.Email.Length > 10)
{
// do gmail stuff
}

Why does a role shows as "not exist" even when present in the database (asp.net mvc)

I'm trying to add users to a role when registering a user so i seeded the roles and updated the database with the code below in the migrations.cs class
var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
string[] roleNames = { "Admin", "Reviewer", "User" };
IdentityResult roleResult;
foreach (var roleName in roleNames)
{
if (!RoleManager.RoleExists(roleName))
{
roleResult = RoleManager.Create(new IdentityRole(roleName));
}
}
i tried to fetch the roleNames into a dropdownlist in my accountcontroller class
public ActionResult Register()
{
var model = new RegisterViewModel();
model.RolesList = new SelectList(_db.Roles, "Id", "Name");
return View(model);
}
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser()
{
UserName = model.UserName,
PortalUser = new PortalUser()
{
Email = model.Email,
UserName = model.UserName
}
};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
UserManager.AddToRole(user.Id, model.Roleid);
return RedirectToAction("Index", "ApplicationReview");
}
else
{
AddErrors(result);
}
}
model.RolesList = new SelectList(_db.Roles, "Id", "Name");
// If we got this far, something failed, redisplay form
return View(model);
}
However the debugger showed an error at this point
UserManager.AddToRole(user.Id, model.Roleid);
Role bec759ac-55ca-40f0-a8b8-00de314dd2b3 does not exist.
however this role exist in the database so i'm confused as to what the problem is
The second parameter is the string role, as in "Reviewer" not the id of the role. It's erroring out because there is literally no role with Name equal to that GUID.
See: https://msdn.microsoft.com/en-us/library/dn497483(v=vs.108).aspx

Categories