Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 3 using Authentication

Tags:

How can I save something using FormsAuthentication? I don't want to store UserId through URL's.

For example, now I have this code:

//UserController class: [HttpPost] public ActionResult LogOn(LogOnModel model, string returnUrl) { if (ModelState.IsValid) {   if (repository.ValidateUser(model.Login, model.Password))   {     FormsAuthentication.SetAuthCookie(model.Login, model.RememberMe);     if (Url.IsLocalUrl(returnUrl))     {       return Redirect(returnUrl);     }     else     {       return RedirectToAction("Project", "Index");     }   }   else   {      ModelState.AddModelError("", "Incorrect name or password.");   } }  return View(model); } 

ProjectController class:

public ViewResult Index() {     return View(repository.GetUserProjects(         this.ControllerContext.HttpContext.User.Identity.Name)); } 

ProjectRepository:

ProjectsContext context = new ProjectsContext(); UsersContext uCnt = new UsersContext();  public IEnumerable<Project> GetUserProjects(String username) {     if (String.IsNullOrEmpty(username))         throw new ArgumentNullException("username", "Login is empty");     return this.uCnt.Users                .FirstOrDefault(u => u.Login == username)                .Projects                .ToList(); } 

ProjectController and ProjectRepository don't looks like good code... Maybe someone can give advise, how to store UserID without using URL's? Best way to do this is save IDs on autorisation, I think. I don't found any properties in User.Identity to do this...

UPD

I beg a pardon, but I forgot to say that I'm using MVC-3 with Razor view. And that UserId is not a string (User.Identity.Name is a string) it could be GUID or maybe my own object...

like image 865
RAMe0 Avatar asked Nov 21 '10 10:11

RAMe0


People also ask

What is the difference between authentication and authorization in MVC?

In simple terms, authentication is the process of verifying who a user is, while authorization is the process of verifying what they have access to.

Is ASP.NET identity support third party authentication?

The Identity framework is another dependency that we will add to our application in the project. js file. This framework allows us to add features where users can register and log in with a local password. The framework also supports two-factor authentication, third-party identity providers and other features.


2 Answers

Save the UserID in the UserData property of the FormsAuthentication ticket in the authorization cookie when the user logs on:

string userData = userID.ToString();  FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, user.Email,     DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),     createPersistentCookie, userData); string hashedTicket = FormsAuthentication.Encrypt(ticket);  HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashedTicket); HttpContext.Current.Response.Cookies.Add(cookie); 

You can read it back in the PostAuthenticateRequest method in Global.asax:

HttpCookie formsCookie = Request.Cookies[FormsAuthentication.FormsCookieName];  if (formsCookie != null) {     FormsAuthenticationTicket auth = FormsAuthentication.Decrypt(formsCookie.Value);      Guid userID = new Guid(auth.UserData);      var principal = new CustomPrincipal(Roles.Provider.Name, new GenericIdentity(auth.Name), userID);      Context.User = Thread.CurrentPrincipal = principal; } 

Note that in this case, CustomPrincipal derives from RolePrincipal (although if you're not using Roles, I think you need to derive from GenericPrincipal), and simply adds the UserID property and overloads the constructor.

Now, wherever you need the UserID in your app, you can do this:

if(HttpContext.Current.Request.IsAuthenticated)     Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID; 
like image 124
TheNextman Avatar answered Sep 19 '22 14:09

TheNextman


Why not first make all your authorization calls via an interface. This way all of your code which uses authentication does not need to be concerned about how the login is performed, or how the Indentity is stored, etc.

public interface IAuthorization {     bool ValidateUser(LoginUser u, string password);     LoginUser GetCurrentUser();     void LogIn(LoginUser user);     void LogOut();     IIdentity GetCurrentUserIdentity(); } 

Implemenation for the IIdentity GetCurrentUserIdentity could be any way you like, but is commonly seen as a call to "HttpContext.Current.User.Identity"

public class Authorization : IAuthorization {     /// <summary>     /// Get the IIdentity for the current logged in user     /// </summary>     /// <returns>IIdentity</returns>     public virtual IIdentity GetCurrentUserIdentity()     {         return HttpContext.Current.User.Identity;     }      /// <summary>     /// Log the user in     /// </summary>     /// <param name="user">User details</param>     public void LogIn(LoginUser user)     {         InvalidCredentialsOnNullUser(user);         FormsAuthentication.SetAuthCookie(user.Name, false);     }      /// <summary>     /// Log the user out     /// </summary>     public void LogOut()     {         FormsAuthentication.SignOut();     }      private static void InvalidCredentialsOnNullUser(LoginUser user)     {         if (user == null)         {             throw new InvalidCredentialException("That user doesn't exist or is not valid.");         }     }      // other methods....  } 

The LoginUser class you see is information which is retrieved about a membership user. This is commonly done via a MembershipProvider but of course can be done other ways.

public class LoginUser {     public string Name;     public Guid Key;     public string EmailAddress;     public bool IsApproved;     public bool IsLockedOut;     public DateTime CreationDate;     public DateTime? LastLoginDate;     public DateTime? LastPasswordChangedDate; } 
like image 22
CRice Avatar answered Sep 20 '22 14:09

CRice