On MVC 5, after Signing In, Identity is still Unauthenticated - asp.net-mvc

In my login page, I have sign-in code like this ...
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
However, when I check User.Identity right after Signin, it is still Unauthenticated
this.User.Identity.IsAuthenticated is returning false.
Anything I am missing ??

The this.User.Identity.IsAuthenticated is not true until the next request. In my case I redirect to the Home/Index. Once inside HomeController.Index() method I see that IsAuthenticated == true.
From here: http://msdn.microsoft.com/en-us/library/twk5762b.aspx
The forms-authentication ticket supplies forms-authentication information to the next request made by the browser.

I'm assuming you're using ASP.NET Identity. Here is a working template and see whats different in your code.
Model:
public class LoginViewModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
Controller:
//
// GET: /My/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /My/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid account name or password.");
}
}
return View(model);
}
Page:
#using (Html.BeginForm("Login", "My", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<hr />
#Html.ValidationSummary(false)
<div class="form-group">
<p class="col-md-2 control-label"><strong>Account</strong></p>
<div class="col-md-10">
#Html.TextBoxFor(m => m.UserName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.UserName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" /> | #Html.ActionLink("Cancel", "Index", "Explore")
</div>
</div>
}

Related

Redirect user to original url after login in asp net mvc

i want to redirect original page after login
public ActionResult UnAuthorize(string ReturnUrl)
{
return Redirect("/Account/SignIn?ReturnUrl=" + ReturnUrl);
}
url : http://localhost:18908/Account/SignIn?ReturnUrl=/Customer/Index
public JsonResult SignIn(SignInModel model, string returnUrl)
{
try
{
return Redirect(returnUrl);
}
But returnUrl return value of null or empty
using System;
using System.Web.Mvc;
namespace WebApplication1.Controllers
{
public class SignInModel
{
public string Name { get; set; }
}
public class AccountController : Controller
{
public ActionResult UnAuthorize(string ReturnUrl)
{
return Redirect("/Account/SignIn?ReturnUrl=" + ReturnUrl);
}
[HttpGet]
public ActionResult SignIn(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
public ActionResult SignIn(SignInModel model, string returnUrl)
{
try
{
return Redirect(returnUrl);
}
catch (Exception ex)
{
throw;
}
}
}
}
SignIn view
#model WebApplication1.Controllers.SignInModel
#{
ViewBag.Title = "View";
}
<h2>View</h2>
#using (Html.BeginForm("SignIn", "Account", new { ReturnUrl = ViewBag.ReturnUrl }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SignInModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Customer Index View
#{
ViewBag.Title = "Customers";
}
<h2>Customer</h2>
Focus on HttpGet SingIn action and SignIn view.
try: http://localhost:18908/Account/UnAuthorize?ReturnUrl=/Customer/Index

MVC Login modal not logging in

I'm using an html form to post form data for logging in. I put it in a modal but it does absolutely nothing other than redirect to main page, and append the verification token, id and password to the url. Is there any reason why? It doesn't even enter the account controller
I just took the post request from the default Login class that comes with mvc projects and put it inside the modal.
AccountController.cs:
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return PartialView("Login", 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 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);
}
}
Login.cshtml
#using Products.Models
#model LoginViewModel
#{
ViewBag.Title = "Log in";
}
<head>
<link rel="stylesheet" href="~/Content/loginmodal.css">
</head>
<!-- Modal -->
<div id="modal" class="modal">
<div class="modal-content">
<div class="modal-body">
<div class="Absolute-Center is-Responsive">
<div id="logo-container"></div>
<div class="col-sm-12 col-md-10 col-md-offset-1">
<form action="" id="loginForm">
#using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
#Html.TextBoxFor(m => m.Email, new { placeholder = "E-mail", #class = "form-control" })
#Html.ValidationMessageFor(m => m.Email, "", new { #class = "text-danger" })
</div>
<div class="form-group input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
#Html.PasswordFor(m => m.Password, new { placeholder = "Password", #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password, "", new { #class = "text-danger" })
</div>
<div class="form-group">
<input type="submit" value="Log in" class="btn btn-def btn-block" />
</div>
<div class="form-group text-center">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
Forgot Password | Support
</div>
}
</form>
</div>
</div>
</div>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
LoginViewModel:
public class LoginViewModel
{
[Required]
[Display(Name = "Email")]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
In your code you have <form action="" id="loginForm"> and Html.BeginForm() on the following line. The Html.BeginForm() renders another <form> element, nested in your case - which is not valid HTML. Browser probably takes the outer <form> where you specified action="", that is why it is not entering your Account controller.
remove this form
form action="" id="loginForm"
as you are creating 2 forms.
#using (Html.BeginForm . . .) creates a form dynamically which will hit your actionresult.

Form Submit Not Work in MVC 5 Project

My Submit Form Button Not Working ..
When I press on Login Button Nothing Happens ...
I had set breakpoint in my code and Login Post Action not Called after Submit Button Click .
I can fix my problem with JQuery ajax codes but I don't want use JQuery Ajax for submitting Form ..I want to understand and resolve this MVC problem
thank you ...
User Model :
namespace Models
{
public class User : BaseEntity
{
public User() : base()
{
}
[System.ComponentModel.DataAnnotations.Required]
public string Username { get; set; }
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.DataType(System.ComponentModel.DataAnnotations.DataType.Password)]
public string Password { get; set; }
}
}
BaseEntity Class has only Id (System.Guid) Property
Controller :
public class AdminController : Infrastructure.BaseController
{
[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ActionResult Index()
{
return View();
}
[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ActionResult Login()
{
return View();
}
[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ActionResult Edit()
{
return View();
}
[System.Web.Mvc.HttpPost]
[System.Web.Mvc.ValidateAntiForgeryToken]
public System.Web.Mvc.ActionResult Login([System.Web.Mvc.Bind(Include = "Id,Username,Password")] Models.User user)
{
string password = AAk.Security.Hashing.GetMD5(user.Password);
Models.User oUser = MyDatabaseContext.Users
.Where(current => current.Username.Contains(user.Username))
.Where(current => current.Password == password)
.FirstOrDefault();
if(oUser != null)
{
System.Web.Security.FormsAuthentication.SetAuthCookie(user.Username, false);
Session["AdminUserId"] = user.Id;
return (RedirectToAction("Edit", "Admin"));
}
else
{
//ModelState.AddModelError(string.Empty, "Login Failed!");
PageMessages.Add(new Infrastructure.PageMessage(Infrastructure.PageMessage.Types.Error, "Login Failed!"));
}
return (View(model: user));
}
}
Login.cshtml
#model Models.User
#{
ViewBag.Title = "Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Login</h2>
#using (Html.BeginForm("Login", "Admin", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.Partial(partialViewName: "~/Views/Shared/_PageMessages.cshtml")
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.Username, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "form-control", #id = "username" } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control", #id = "password" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" id="login-button" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>

how to make 'remember me' lasts longer in browsers in asp.net MVC project

I am working on asp.net MVC project. I have standard Account controller which it creates it self after change the project authentication to `individual User Accounts after creating the project.
it has Remember me check box it self in login view. my problem is that it remembers the user information (username and password) less than 10 minutes. how I can do something to make this time long lasts more than 2 hours for example or more.
here is my account controller login action:
[Authorize]
public class AccountController : Controller
{
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 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);
}
}
}
and here is its view if needed:
<div class="row">
<div class="col-md-8">
<section id="loginForm">
#using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" />
</div>
</div>
//Enable this once you have account confirmation enabled for password reset functionality
<p>
#Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>
}
</section>
</div>
<div class="col-md-4">
<section id="socialLoginForm">
#Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>

What could be causing for ASP.NET MVC form to not properly submit/deserialize?

This looks like it should be working, yet the form submits with model not properly deserialized. Using latest ASP.NET MVC from nuget. .NET 4.5
A very standard user-registration View/Controller.
View:
#model Alertera.Portal.Web.Models.RegisterViewModel
#{
ViewBag.Title = "Register";
}
<h2>#ViewBag.Title.</h2>
#using (Html.BeginForm("Register", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<hr />
#*#Html.ValidationSummary()*#
<div class="form-group">
#Html.LabelFor(m => m.UserName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.UserName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.LastName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.LastName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.ConfirmPassword, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.ConfirmPassword, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}
Controller:
// POST: /Account/Register
[AcceptVerbs(HttpVerbs.Post)]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new User
{
UserName = model.UserName,
FirstName = model.FirstName,
LastName = model.LastName
};
user.SetEmail(model.Email);
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
_bus.Publish(new UserCreated(user));
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
All of the posts are coming in with model being empty or forgery token not present (depends if I enable or disable verficiation). I'm simply stumped and don't know where to look.
** EDIT **
If I disable antiforgery, ModelState is invalid, all of the fields in the model are empty and error messages state that fields are required.
I'm using Autofac with MVC extensions and Model binder is registered like so:
builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
builder.RegisterModelBinderProvider();
Autofac is working in general, as controller is instantiated properly and is injected with propery dependencies.
Edit 2:
Created a custom binder by inheriting from the DefaultModelBinder, per suggestion, so that I could see the transformation. It looks like the bindingContenxt's model is null
The view model itself is here:
public class RegisterViewModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string FirstName { get; set; }
}
After a full day of trubleshooting, updating all of the nuget packages, making sure that web.config's are all tight and contain proper assembly redirects, routes are neat, and even repair of .NET framework and other time consuming and irrelevant activities, I've finally figured this out:
A few weeks prior, we've introduced an Autofac binding that would capture serialized HttpContext along with other relevant data for when the logging framework would need it. (Imagine being able to log request information alongside a full exception stack inside a business object without polluting business logic with session/logging data.)
Unfortunately, as a part of the binding creation, the HttpContext was being serialized by Json.net and not at the time of the logging of the event, but at the time of the binding.
Apparently, when Json.net seralizes HttpContext, it actually reads the streams inside it for the first time, causing the submitted form data to be read, so that when Controller is instantiated and data for it is posted, the streams have already been read and Request.Form colection is empty.
Simple fix to only create a delegate to serialize HttpContext appears to have fixed the issue

Resources