Show error message for wrong password - asp.net

I have this login code and I want to show (error message "Invalid User&Password") If someone input a wrong password, currently right now my code is just redirecting to same page if error occur.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Login l,string ReturnUrl="")
{
using (graceEntities dc = new graceEntities())
{
var user = dc.tbl_User.Where(a => a.UserName.Equals(l.Username) && a.Password.Equals(l.Password)).FirstOrDefault();
if (user != null)
{
FormsAuthentication.SetAuthCookie(user.UserName,l.RememberMe);
if (Url.IsLocalUrl(ReturnUrl))
{
return Redirect(ReturnUrl);
}
else
{
return RedirectToAction("Index","Main");
}
}
}
ModelState.Remove("Pasword");
return View();
}

You need to handle the case where the user is not found in the database. Please read the comments inline in code below for further clarification:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Login model, string ReturnUrl = "")
{
// 1. Do validation and return view if validation errors
if (!ModelState.IsValid)
{
return View(model);
}
// 2. No validation error so search db for user
using (graceEntities dc = new graceEntities())
{
var user = dc.tbl_User
.Where(a => a.UserName.Equals(model.Username) &&
a.Password.Equals(model.Password)).FirstOrDefault();
if (user != null)
{
FormsAuthentication.SetAuthCookie(user.UserName, model.RememberMe);
if (Url.IsLocalUrl(ReturnUrl))
{
return Redirect(ReturnUrl);
}
// No return url, redirect to main/index
return RedirectToAction("Index", "Main");
}
}
// 3. We made it here, so user was not found
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}

Related

Cannot Get ID of user after login using User.Identity.GetUserId()

I am using Microsoft.AspNet.Identity in my application.
The user can Log In and can only see his/her own controller.
Because I've added attributes ([Authorize(Roles = "1")]) and this works fine as well.
But I can't get the user Id by using string users = User.Identity.GetUserId();.
users is always null, and I don't know why.
I am not using default login template.
And one more thing, after login I've done something like this
if (User.IsInRole("1"))
{
return RedirectToAction("Dashboard", "Supplier");
}
else if (User.IsInRole("2"))
{
return RedirectToAction("Dashboard", "Site");
}
but it does not work as well. But when I login and go to controller which has Authorize(Roles ="1") in controller, it does not give any error or redirect to login page.
But when I login with the user (which has Roles="2"), I cannot access the controller with Authorize(Roles="1").
This is how I have configured ASP.Net Identity:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
ExpireTimeSpan = TimeSpan.FromMinutes(5),
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login/Index") });
}
}
}
Update
For Redirection based on Role I've updated my Controller/Action.
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginView login)
{
if (ModelState.IsValid)
{
var user = (from u in db.logins
where u.user_name == login.user_name && u.user_password == login.user_password && u.isactive == 1
select new
{
u.user_name,
u.login_id,
u.user_type,
u.isactive
});
if (user.FirstOrDefault() != null)
{
FormsAuthentication.SetAuthCookie(login.user_name, true);
Session["UserName"] = user.FirstOrDefault().user_name;
string userId = User.Identity.GetUserId();
return RedirectToAction("RedirectToDefault");
}
else
{
ViewBag.error = "User Does Not Exist";
return View(login);
}
}
else
{
ModelState.AddModelError("", "Invalid Credentials");
}
return View(login);
}
And the in RedirectToDefault I've added:
public ActionResult RedirectToDefault()
{
String[] roles = Roles.GetRolesForUser();
string id = User.Identity.GetUserId(); //<- this is null here as well.
string name = User.Identity.GetUserName();
if (roles.Contains("1"))
{
return RedirectToAction("Index", "Supplier");
}
else if (roles.Contains("2"))
{
return RedirectToAction("Index", "Site");
}
and so on..
Any help would be much Appreciated.
From your incomplete code it looks like you are doing everything manually, selecting users from the db and so on.
Try using the SignInManager:
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginView login)
{
if (ModelState.IsValid)
{
var result = await SignInManager.PasswordSignInAsync(login.Username, login.Password, false, shouldLockout: true);
if (result == SignInStatus.Success)
{
//FormsAuthentication.SetAuthCookie(login.user_name, true);
//Session["UserName"] = user.FirstOrDefault().user_name;
//string userId = User.Identity.GetUserId();
//These shouldn't be neede anymore
return RedirectToAction("RedirectToDefault");
}
else
{
ViewBag.error = "User Does Not Exist";
return View(login);
}
}
else
{
ModelState.AddModelError("", "Invalid Credentials");
}
return View(login);
}
I would suggest that you read up on how Identity works, as it does everything for you, however you need to know how to access the data.
You can get user id through UserManager like:
var user = await UserManager.FindAsync(username, password);
Hope this helps someone.

Cannot post update to database. not all code paths return a value

[HttpPost]
public ActionResult UpdateDetail(User user)
{
bool Status = false;
string message = "";
// Model Validation
if (ModelState.IsValid)
{
using (UsersDatabaseEntities ude = new UsersDatabaseEntities())
{
var v = ude.Users.Where(a => a.Email == User.Identity.Name).FirstOrDefault();
user = v;
ude.Entry(User).State = EntityState.Modified;
ude.SaveChanges();
}
return View(user);
}
}
I keep on getting an error while saving data to the database.
UpdateDetail worked while retrieving message, but i keep getting error when saving.
Your issue is if your ModelState.IsValid == false, then you are not returning anything. I put a comment in code below where it is.
Depending on what your logic needs to do, would determine what needs to be returned if IsValid == false
public ActionResult UpdateDetail(User user)
{
bool Status = false;
string message = "";
// Model Validation
if (ModelState.IsValid)
{
using (UsersDatabaseEntities ude = new UsersDatabaseEntities())
{
var v = ude.Users.Where(a => a.Email == User.Identity.Name).FirstOrDefault();
user = v;
ude.Entry(User).State = EntityState.Modified;
ude.SaveChanges();
}
// this is your issue, this needs to be outisde the if statement, or you have to do an else and return null (or whatever you need to based off your logic)
return View(user);
}
}
Keep return statement outside of If statement. this would fix your error.If model is valid model updated with user details from database will be pushed to View. other wise same user model will be pushed to the view.
[HttpPost]
public ActionResult UpdateDetail(User user)
{
bool Status = false;
string message = "";
// Model Validation
if (ModelState.IsValid)
{
using (UsersDatabaseEntities ude = new UsersDatabaseEntities())
{
var v = ude.Users.Where(a => a.Email == User.Identity.Name).FirstOrDefault();
user = v;
ude.Entry(User).State = EntityState.Modified;
ude.SaveChanges();
}
}
return View(user);
}

Working on Sign up page with ASP .net

I'm an intern developer and learning to code in ASP .net with mvc framework.
I'm working on a sign up page for a website where the users have to click on the link provided to validate their account with a website while registering their account.
Now, if the users have not clicked on the link which was sent to them in an email while registering then the user will not have a valid account and for those users I want that this message should be displayed "Please confirm your link to activate your account".
For that my code is as below but this code is giving me errors while I run it (looks like it is not going into the else condition.
My code is as below and is not working. Can someone please help me on this-
public ActionResult Login(LoginModel model, string returnUrl)
{
Session["CheckAmountOfSites"] = true;
ViewBag.SuggestBrowser = false;
if (ModelState.IsValid)
{
try
{
model.UserName = model.UserName.Trim().ToLower();
if (ValidateUser(model.UserName, model.Password))
{
if (activated == true)
{
FormsAuthentication.SetAuthCookie(model.UserName.ToLower(), model.RememberMe);
--Some more stuffs in if condition but have not been pasted completely here for --security reasons
} }
This is my else condition--But somehow its not entering the else part.
//validate user is not true
else
{
//ModelState.AddModelError("", "The Email or Password provided is incorrect.");
if (activated == false)
{
return RedirectToAction("Confirm", "Account", new { userName = model.UserName });
}
}
Confirm action--
[AllowAnonymous]
public ActionResult Confirm( string userName)
{
using (var db = SiteUtil.NewDb)
{
var user = db.Users.Where(n => n.Username == userName && n.CanLogin == false).FirstOrDefault();
if (user.CanLogin == false)
{
ViewBag.Email = "Please confirm your mail to activate your account";
}
}
return View();
}
public bool ValidateUser(string userName, string password)
{
using (var db = SiteUtil.NewDb)
{
var user = db.Users.Where(n => n.Username == userName && n.IsActive).FirstOrDefault();
if (user == null)
{
return false;
}
if (user.CanLogin == false)
{
//Mod("Email", "please confirm the mail which was sent to you");
//ViewBag.Email = "please confirm the mail which was sent to you";
return true;
}

Save data instead of adding to database

I'm trying to edit an article in my asp.net mvc project. This is what I do when I create a project:
public ActionResult Create(ArticleViewModel model)
{
if (ModelState.IsValid)
{
try
{
// Get the userID who created the article
User usr = userrepo.FindByUsername(User.Identity.Name);
model.UsernameID = usr.user_id;
repository.AddArticle(model.Title, model.Description, model.ArticleBody);
}
catch (ArgumentException ae)
{
ModelState.AddModelError("", ae.Message);
}
return RedirectToAction("Index");
}
return View(model);
}
In my repository:
public void AddArticle(string Title, string Description, string ArticleBody)
{
item Item = new item()
{
item_title = Title,
item_description = Description,
article_body = ArticleBody,
item_createddate = DateTime.Now,
item_approved = false,
user_id = 1,
district_id = 2,
link = "",
type = GetType("Article")
};
try
{
AddItem(Item);
}
catch (ArgumentException ae)
{
throw ae;
}
catch (Exception)
{
throw new ArgumentException("The authentication provider returned an error. Please verify your entry and try again. " +
"If the problem persists, please contact your system administrator.");
}
Save();
// Immediately persist the User data
}
public void AddItem(item item)
{
entities.items.Add(item);
}
But now I want to edit an article, this is what I have till now:
public ActionResult Edit(int id)
{
var model = repository.GetArticleDetails(id);
return View(model.ToList());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ArticleViewModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the User
try
{
item Item = repository.GetArticleDetailsByTitle(model.Title);
Item.item_title = model.Title;
Item.item_description = model.Description;
Item.article_body = model.ArticleBody.
// HERE I NEED TO SAVE THE NEW DATA
return RedirectToAction("Index", "Home");
}
catch (ArgumentException ae)
{
ModelState.AddModelError("", ae.Message);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
As you can see I check the adjusted text and drop it in "Item". But how can I save this in my database? (the function in my repository)
I think your save() method had entityobject.SaveChanches()
So you want to call that save() method in here
try
{
item Item = repository.GetArticleDetailsByTitle(model.Title);
Item.item_title = model.Title;
Item.item_description = model.Description;
Item.article_body = model.ArticleBody.
**Save();**
return RedirectToAction("Index", "Home");
}
should be need to only Save() method, could not need to AddItem() method .
I'm afraid you'll need to get article again from database, update it and save changes. Entity framework automatically tracks changes to entites so in your repository should be:
public void EditArticle(Item article)
{
var dbArticle = entities.items.FirstOrDefault(x => x.Id == article.Id);
dbArticle.item_title = article.item_title;
//and so on
//this is what you call at the end
entities.SaveChanges();
}

Transfer data to ApplicationController

I'm trying to do a login module with view master page. First user access to a home page with a login form, when user click login, page should redirect to a UserLoginController first and then redirect to another PanelController which holds all pages with same master page. I want to show different menus by different user's permission. As I refer a article http://www.asp.net/mvc/tutorials/passing-data-to-view-master-pages-cs I create a abstract class ApplicationController, the PanelController inherit it. In the constructor, I want to get the login user's information to identify user's permission, but it seems Request and Session is not available. Pls see code.
First the login Javascript
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$(btnLogin).click(function () {
var sso = $(txtSSO).val();
var pwd = $(txtPwd).val();
if (sso == "")
{ alert("Please input your SSO number"); }
else if (pwd == "")
{ alert("Please input your password"); }
else {
jQuery.ajax(
{ url: '<%:Url.Action("UserLogin", "UserLogin")%>',
data: { sso: sso, pwd: pwd },
success: function (data) {
window.location = '<%: Url.Action("Demo","Panel") %>';
}
}
);
}
});
});
</script>
The UserLoginController
public ActionResult UserLogin()
{
string sso = "";
string pwd = "";
try
{
if (Request.IsAjaxRequest())
{
sso = Request.Params["sso"].ToString();
pwd = Request.Params["pwd"].ToString();
}
Regex reg = new Regex("^[0-9]{9}$");
if (!reg.Match(sso).Success || pwd == "")
{
ViewData["errorMsg"] = "Either your UserID or your Password is incorrect";
return View("Index");
}
SystemAdminEntities entity = new SystemAdminEntities();
var result = entity.ValidateUserLogin(sso, pwd).FirstOrDefault();
if (result == 1)//User is found
{
int isso = Convert.ToInt32(sso);
var dbEmp = (from e in entity.sys_employee
where e.sso == isso
select e);
SysEmployee emp = dbEmp.FirstOrDefault<SysEmployee>();
LogonUserModel currentUser = LogonUserModel.GetUser();
currentUser.CopyUserInfo(emp);
//FormsAuthenticationTicket ticket=new
FormsAuthentication.SetAuthCookie(currentUser.SSO.ToString(), true);
Session.Add("emp", currentUser);
this.Session.Add("sso", currentUser.SSO);
this.Session.Add("empid", currentUser.EmpID);
this.Session.Add("ename", currentUser.EName);
return RedirectToAction("Demo", "Panel");//重定向到 Demo
}
else if (result == 0)//User is not found
{
ViewData["errorMsg"] = "User isn't found";
return View("Index");
}
else if (result == 2)//Password not correct
{
ViewData["errorMsg"] = "Password Error";
return View("Index");
}
return View("Index");
}
catch { return View("Index"); }
}
The ApplicationController
public abstract class ApplicationController : Controller
{
private SystemAdminEntities _entities = new SystemAdminEntities();
public ApplicationController()
{
//根据人员判断权限
int sso = 0;//= Request.Form["sso"].ToString();
try
{
sso = int.Parse(Session["sso"].ToString());
var e = (from emp in _entities.sys_employee//得到对应的用户
where emp.sso == sso
select emp
);
SysEmployee loginUser = e.FirstOrDefault<SysEmployee>();
ViewData["modules"] = loginUser.SysHasPerm;
}
catch
{
ViewData["modules"] = null;
}
}
The PanelController
public class PanelController : ApplicationController
{
//
// GET: /Panel/
public ActionResult Index()
{
return View();
}
public ActionResult Demo()
{
return View();
}
}
ViewData is used in MVC to pass data from Controllor to View
and Tempdata is used to pass data from one Controllor to other
Refer Passing State Between Action Methods
See this example for Step by step -

Resources