ASP.NET MVC Custom Authorization : AuthorizeAttribute - asp.net-mvc

I'm following this tutorial link
I have a table users {iduser, user, pass, role}
I'm using this users : string[] users = db.users.Select(t => t.user).ToArray();
instead of : string[] users = Users.Split(','); Is it ok ?
My problem is with roles : SiteRoles role = (SiteRoles)httpContext.Session["role"];
Q: Where do I store the role for my user ?
My simplified account controller:
[HttpPost]
public ActionResult Login(LoginModel model)
{
HeliosEntities db = new HeliosEntities();
if (ModelState.IsValid)
{
bool userok = db.users.Any(t => t.user == model.UserName && t.pass == model.Password);
if (userok == true)
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToAction("Index", "Home");
}
{
ModelState.AddModelError("", "Incorect password or user!");
}
}
return View();
}

A quick look at your link above shows that it is getting the user's role from session:
(SiteRoles)httpContext.Session["role"];
so you need to set the session value when the user logs in, for example:
var userRole = Roles.Admin | Roles.User;
httpContext.Session["role"] = role;
I don't know where you store the information about what role the user is in though.

Related

How to Pass Value from a login Page

Hello I need help please
I am creating my first asp mvc Webpage.
I created a login and registration page connected with database.
I want to pass CustomerId from the customer that logged in to a Bookings table
So that it shows bookings related to that customer only.
Bookings table has CustomerId as a foreign key. This is what I have done so far.
public class BookingController : Controller
{
// GET: Booking
public ActionResult Index(int customerId)
{
TravelExpertsEntities bookingdb = new TravelExpertsEntities();
List<Booking> bookings = bookingdb.Bookings.Where(book =>
book.CustomerId == customerId).ToList();
return View(bookings);
}
}
}
//This is from login Controller
public ActionResult Login(Customer reg)
{
if (ModelState.IsValid)
{
var details = (from userlist in db.Customers
where userlist.UserName == reg.UserName &&
userlist.Password == reg.Password
select new
{
userlist.CustomerId,
userlist.UserName
}).ToList();
if (details.FirstOrDefault() != null)
{
Session["CustomerId"] =
details.FirstOrDefault().CustomerId;
Session["Username"] = details.FirstOrDefault().UserName;
return RedirectToAction("Index", "Booking");
}
}
else
{
ModelState.AddModelError("", "Invalid UserName or Password");
}
return View(reg);
}
I was able to pull all bookings but I want to filter it with the Customer that logged in.
Replace your RedirectToAction as below, to pass customerId as parameter
var CustomerIdparam=details.FirstOrDefault().CustomerId;
RedirectToAction("Index", "Booking", new{customerId=CustomerIdparam});

How to get items for logged in user ASP.NET MVC

I am trying to show booking of logged in user from database, but its show all data from all user. this is the original code:
// GET: Bookings
public ActionResult Index()
{
var bookings = db.Bookings.Include(b => b.Room).Include(b => b.Register);
return View(bookings.ToList());
}
Here what I have tried but the output show an error,
public ActionResult Index()
{
var bookings = db.Bookings.Include(b => b.Room).Include(b => b.Register == Session["id"]);
return View(bookings.ToList());
}
This is the user table in the database, so if I login as user no.1, the booking data should display only customerID no.1, but the problem is, the data show all user bookings.
Here is the image of booking db,
Here is the code for login:
[HttpPost]
public ActionResult Login(Register login)
{
using (HotelBookingEntities db = new HotelBookingEntities())
{
var userDetails = db.Registers.Where(x => x.email == login.email && x.password == login.password).FirstOrDefault();
if (userDetails == null)
{
ViewBag.WrongMessage = "Wrong username or password";
return View("Login", login);
}
else
{
Session["id"] = userDetails.id;
Session["username"] = userDetails.username;
return RedirectToAction("Index", "Rooms");
}
}
}
Try as follows:
public ActionResult Index()
{
int userId = Convert.ToInt32(Session["id"]);
var bookings = db.Bookings.Where.Include(b => b.Room).Where(b => b.CustomerID == userId).ToList();
return View(bookings);
}

ASP.NET MVC 5 - let admin change other users password. Password changed in database but can't login

I'm told to make admin have a functionality to change other users password without knowing their original password. I wrote a code that changes and saves password successfully in database, but when I try to login as that user I can't.
UsersController:
public ActionResult ChangePassword()
{
return View();
}
[HttpPost]
public ActionResult ChangePassword(int id, ViewModels.ChangePasswordViewModel model)
{
if (!SessionControlService.CheckIsLoginStillTrue(_loginsService, HttpContext))
return RedirectToAction("Login", "Account");
if (!User.IsInAnyRoles("Admin", "PropertyManager"))
return RedirectToAction("Error", "Errors",
new { error = Facility.Web.Resources.Resources.ErrorNotHavePermission });
var user = _userService.GetUser(id);
if (user == null)
return RedirectToAction("Error", "Errors",
new { error = Facility.Web.Resources.Resources.ErrorURLNotExist });
user.Password = model.NewPassword;
_userService.UpdateUser(user);
return RedirectToAction("Details", new { id = id });
}
Why can't I use the changed password which is saved in the database to login?
How can I make this work?
In ASP.NET MVC5, password is hashed... you cannot save a plaintext password like that.
You need to use these two methods:
var manager = new ApplicationUserManager(...);
var token = manager.GeneratePasswordResetToken(userId)
manager.ResetPassword(userId, token, newPassword)
You could also try ApplicationUserManager.UpdatePassword(...), or RemovePassword(...) and AddPassword(...)
ApplicationUserManager is normally in IdentityConfig.cs

MVC Display data based on users login

I have this table where displaying the list of userID+SubjectID, now i want is,if the user who Logged in can only see the list of Subject that belongs to the current user,is it possible? then should i need to use asp.net identity? currently i am using empty template with custom login Authentication + Roles only, any idea on what is the best way to handle this type of scenario? all i want is my tables will show data based on the current user logged in.
Example: If User1 logged in then User1 will only see subjects belong to user1..
Note:
i was searching for tutorials on showing data based on the current user logged in, but i couldn't find,any one has better idea? or link can share with me? i don't know the better word for my scenario i just call it "show data based on current user",i appreciate if anyone can solve this..thanks in advance..
Table Controller:
[CostumAuthorize(Roles = "Admin,Teacher")]
public ActionResult Subject_List(int id)
{
var test = db.SubjectTeachers.Where(x => x.Users.Any(n => n.UserID == id)).ToList();
var subjectTeachers = db.SubjectTeachers.Include(s => s.Levels).Include(s => s.Subjects).Include(s => s.Users).Where(u => u.LevelID == id);
return View(subjectTeachers.ToList());
}
Account controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Login l, string ReturnUrl = "")
{
if (!ModelState.IsValid)
{
return View(l);
}
using (MyContext dc = new MyContext())
{
var user = dc.Users.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);
}
return RedirectToAction("Index", "Home");
}
}
ModelState.AddModelError("", "Invalid Login.");
return View(l);
}
[Authorize]
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Account");
}
}
If you can get the logged-in userid then simply use that to get Corresponding Subjects list.........
int userid = Membership.GetUser(User.Identity.Name).ProviderUserKey;
[CostumAuthorize(Roles = "Admin,Teacher")]
public ActionResult Subject_List()
{
var test = db.SubjectTeachers.Where(x => x.Users.Any(n => n.UserID == userid )).ToList();
return View(test.ToList());
}

Authentication & Authorization Role issue

i'm having a controller name UserController in Admin Area (section). In which i can assign them Roles Admin (A) to User (U) or User (U) to Admin (A).
when I change role of any user it updated successfully in database also ,but when I login from application that user of which i had changed the role so user contains its old role.I have put the break point also the variable 'role' is returning the previous Role. i'm surprised that how can 'role' variable return its old role.
public override string[] GetRolesForUser(string username)
{
string[] role = { obj.GetAll().Where(x => x.EmailAddress == username).FirstOrDefault().Role };
return role;
}
User Controller AssignRole Action in this code i'm updating the Role
public ActionResult AssignRole(int id, string role)
{
try
{
BOL.tbl_Login user = (BOL.tbl_Login)obj.login.GetById(id);
if (role == "A")
{
user.Role = "U";
}
else if (role == "U")
{
user.Role = "A";
}
else
{
user.Role = "U";
}
obj.login.Update(user);
TempData["Msg"] = "Operation Successfully!";
}
catch (Exception ex)
{
TempData["Msg"] = "Error " + ex.Message;
}
return RedirectToAction("_Index");
}
and i'm also using
[Authorize(Roles = "A")]
I think Entity Framework not returning the newest data.
here is the Data access layer code
public override void Update(T data)
{
obj.Entry(data).State = EntityState.Modified;
obj.Configuration.ValidateOnSaveEnabled = false;
Save();
obj.Configuration.ValidateOnSaveEnabled = true;
}
Your problem is that role is saving both previous and current values. AsNoTracking function do not save previous values it only shows current value. Put my code there where you are getting roles or above your method 'getroles' so your problem will be solved
public override IEnumerable<T> GetAll()
{
return obj.Set<T>().AsNoTracking().ToList();
}

Resources