Im getting really lost on how to use HttpContext.User. I read everywhere that its great for FormAutherication, but i just cant see how it works. If i do something like this:
ControllerContext.HttpContext.User = new GenericPrincipal(GetUser(username, password), roles);
What does ControllerContext.HttpContext.User contain? and how do i access information about the user this way?
Im think that i have a Action like this:
public User GetUser(string username, string password)
{
try
{
var user = (from u in dm.Users
join r in dm.Roles
on u.Role_ID_FK equals r.RoleID
where u.Username.Equals(username) && u.Password.Equals(password)
select u).Single();
return user;
}
catch (Exception e)
{
return null;
}
}
And then if i want user information in my view, like the user name or role, i can call ControllerContext.HttpContext.User.Username in my View. But this is diffenrently the wrong way to look at it.
So can you guys give me a kick in the rigth direction or post a link to a site which can?
I'm not sure exactly what you are trying to do with the code you posted, but here's some help with HttpContext.User. In layman's terms it represents the current user requesting the particular page, and actually within your Controller you can just reference it as "User" without the prefix.
User.Identity will let you know if the user is authenticated, and if so their username and how they authenticated (Forms or Windows).
It's generally used to get the username of the user requesting the page so your controller actions can perform the correct duties. Something like:
public ActionResult Index()
{
//you should probably use the [Authorize] attribute on the Action Method
//but you could check for yourself whether the user is authenticated...
if (!User.Identity.IsAuthenticated)
return RedirectToAction("LogIn");
MyUser u = repository.GetUser(User.Identity.Name); //lookup user by username
ViewData["fullname"] = u.FullName; //whatever...
return View();
}
In this example, if the user hasn't been authenticated, they will be redirected to a LogOn page, and if they have been, the Action method is using the User.Identity.Name (which is the username they logged in with, or their Windows login) to lookup and return an instance of a MyUser object from your database and puts the user's full name in ViewData to be displayed.
In your login code use:
FormsAuthentication.SetAuthCookie("userName", remeberMe);
to set the authenticated user, then you can use
<%= User.Identity.Name %>
<%= User.IsInRole("role") %>
Related
Using VS 2013, standard MVC template, and the Identity provider framework
The user is logged in, and I have:
//....
UserManager.AddToRole(User.Identity.GetUserId(), "Members"); # Line X
RedirectToAction("Index", "Members");
And the Members controller is as follows:
[Authorize(Roles="Members")]
public class MembersController : Controller
{
// GET: Members
public ActionResult Index()
{
return View();
}
}
After Line X is executed, I can confirm that the user is added to the table dbo.AspNetUserRoles. However, the user upon reaching the Members controller fails the role check. User.IsInRole("Members") returns false.
If the user logs off and then logs in again, then access to the Members controller will go through, ie User.IsInRole("Members") now returns true.
Is there some caching? Why the delay? How do I overcome it?
I also tried converting the method at Line X to an async method and used UserManager.AddToRoleAsync. The same delayed effect is still there.
The identity information(roles,claims) are put into the cookie when the user logs in. Since the user is already logged in, this line of code UserManager.AddToRole(User.Identity.GetUserId(), "Members") will update the db , but not the cookie. You have to have to re-issue the cookie.
Try add SignInManager.SignIn(user, false, false); (if you dont have user, var user = UserManager.FindById(User.Identity.GetUserId())) before RedirectToAction("Index", "Members");
So in my .net application I have three controllers
Home
Kitchen
Institution
When the user logs in, I get what controller the user can go. I have defined some roles and using those I get which user needs to go where.
So for example if a user Bob is a cook. When Bob logs in, he is taken to the kitchen dashboard. But if Bob types in the URL ../Home/Dashboard there is nothing stopping him for going in there. What should be done in order to restrict Bob accessing any other url?
Also, when the user logs in should I store the information about his role in session?
What is the best practice for this purpose?
You can handle all your requirements in an HttpPost Login Action. See comments for further instructios.
[HttpPost]
[AllowAnonymous]
public ActionResult Login(LoginModel model, string returnUrl)
{
// check first for field validations
if (!ModelState.IsValid)
return View(model);
// validate user agains database
var user = FindUser(model.UserName, model.Password);
if (user == null)
{
ModelState.AddModelError("", "Invalid username or password.");
return View(model)
}
// user is valid, sign in assuming forms authentication, however it's
// best practice to abstract following statement by use of some kind of authentication
// manager (refer to OWIN framework for a better approach).
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
// when returnUrl param is provided
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
// following 'if' - condition dependent on your domain models.
if (user.IsCook)
return RedirectToRoute(/*kitchen route*/);
else
return RedirectToRoute(/*dashboard*/);
}
I am using MVC 5 and have a View that contains a jQuery Ajax call to the controller and retrieve some data. Previously I was unable to make this Ajax GET because the controller is marked [Authorize], so I marked the method as [AllowAnonymous].
At this point I have a need to determine the authenticated user, but User.Identity shows IsAuthenticated = false. This makes sense, but I am needing to know how I can obtain the user's identity within this method. Here is the method:
[AllowAnonymous]
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetDesignParams(string countrycode)
{
ApplicationUser user = UserManager.FindById(User.Identity.GetUserId());
if (user != null)
{
... do something ...
}
... do something else ...
return Json(rules, JsonRequestBehavior.AllowGet);
}
Is there a way of obtaining the user's identity within this routine without passing the user id from the client side Ajax GET?
You need to go through bearer tokens in order to make your API-like method secure
See this: Secure a Web API with Individual Accounts and Local Login
I am creating an application using MVC4. I am trying to work out how to capture when a user logs in.
I thought I could add some code in the login Action in Account controller..
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && _authProvider.Login(model.UserName, model.Password, true))
{
var currentUser = Membership.GetUser();
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
but the currentUser is always null? why is that? How can I fix it?
Thanks
Membership.GetUser() doesn't work because it uses the HttpContext.Current.Identity to retrieve the the user, but this will not get set until the next page refresh.
The reason is that your Login method most likely uses FormsAuthentication.SetCookie() (or some variation) to create an auth ticket, but that ticket has to be read on a page load to be valid. Since the current page is already loaded at this point, authentication is not valid until the next page load.
Regardless, I don't understand why you even need to do this. You already know the users name. It's right there, you pass it to the Login method... model.UserName.
This is my first post here, so hello :) Okay, let's get to the point...
I am writing my first app in ASP.NET MVC Framework and i have a problem with checking privileges to use instances of model classes (read, edit). Sample code looks like this:
// Controller action
[CustomAuthorize(Roles="Editor, Admin")]
public ActionResult Stats(int id)
{
User user = userRepository.GetUser(id);
if (user == null || !user.Activated || user.Removed)
return View("NotFound");
else if (!user.IsCurrentSessionUserOwned)
return View("NotAuthorized");
return View(user);
}
So far authorize attribute protects only controller actions, so my question is: how to make CustomAuthorize attribute to check not only user role, usernames but also did i.e. resources instantiated in action methods (above: User class, but there are other ORM LINQ2SQL classes like News, Photos etc.) All of these object to check have their unique ID's, so user entity have own ID, News have their ID's and UserID field referecned to Users table. How should i resolve that problem?
If i understand right, you want to let the user who write News,Articles to edit his own News or Articles even if he doesnt has the role of "Admin" or "Editor"..
Well that is a tricky one, the simple solution would be:
Let your CustomAuthorize as it is, BUT let it continue to the Action, instead of returning a error View or something just inject an action parameter ie:
CustomAuthorize:
//..Your Role Validation Logic Here...
if (filterContext.ActionParameters.Keys.Contains("isAuthorize"))
{
filterContext.ActionParameters.Remove("isAuthorize");
}
filterContext.ActionParameters.Add("isAuthorize", isAuthorized);
Where isAuthorized will hold the result of the role validation logic.
So in your controller, you must add a 2nd parameter:
[CustomAuthorize(Roles="Editor, Admin")]
public ActionResult Stats(int id, bool isAuthorized)
{
User user = userRepository.GetUser(id);
if (user == null || !user.Activated || user.Removed)
return View("NotFound");
else if (user.Id != CurrentUser.Id && !isAuthorized)
//not Authorized by roles
//not the owner get away from here =D
return View("NotAuthorized");
return View(user);
}
I'm assuming you have access to a CurrentUser that comes from a property in BaseController (abstrac class).
Implementing something more elaborated than that will result in a complex situation.
For instance you can, but not recommended:
A. Send the userID of the owner as a parameter (so every time you send an ID on the url GET or POST request you must add the user ID of the owner as a parameter). But this can lead to really ugly security flaws, because you depend on the userID that is send by the wire that can be tamper by the user and woala! im authorized now.
B. Try to instance the object in the action filter (but you must figure out first what entity you are trying to instance, this can lead to a long switch statement and a 3rd parameter in the CustomAuthorize so you know which entity to get from the DB).