ASP.NET MVC 3 utilizzando l’autenticazione

Come posso salvare qualcosa usando FormsAuthentication? Non voglio memorizzare UserId tramite URL.

Ad esempio, ora ho questo codice:

//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); } 

Classe ProjectController :

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

ProjectRepository :

 ProjectsContext context = new ProjectsContext(); UsersContext uCnt = new UsersContext(); public IEnumerable 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 e ProjectRepository non sembrano un buon codice … Forse qualcuno può dare consigli, come conservare UserID senza utilizzare gli URL? Il modo migliore per farlo è salvare gli ID in caso di authorization, penso. Non ho trovato alcuna proprietà in User.Identity per fare questo …

UPD

Chiedo scusa, ma ho dimenticato di dire che sto usando MVC-3 con Razor view. E che UserId non è una stringa (User.Identity.Name è una stringa) potrebbe essere GUID o forse il mio object …

Salvare l’ID utente nella proprietà UserData del ticket FormsAuthentication nel cookie di authorization quando l’utente accede:

 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); 

Puoi leggerlo di nuovo nel metodo PostAuthenticateRequest 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; } 

Nota che in questo caso, CustomPrincipal deriva da RolePrincipal (anche se non stai usando i ruoli, penso che tu debba derivare da GenericPrincipal), e semplicemente aggiunge la proprietà UserID e sovraccarica il costruttore.

Ora, ovunque sia necessario l’ID utente nella tua app, puoi farlo:

 if(HttpContext.Current.Request.IsAuthenticated) Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID; 

Perché non effettuare prima tutte le chiamate di authorization tramite un’interfaccia. In questo modo tutto il codice che utilizza l’autenticazione non deve preoccuparsi di come viene eseguito il login, o di come viene memorizzata l’id quadro, ecc.

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

Implemenation for thedentity GetCurrentUserIdentity potrebbe essere come preferisci, ma è comunemente visto come una chiamata a “HttpContext.Current.User.Identity”

 public class Authorization : IAuthorization { ///  /// Get the IIdentity for the current logged in user ///  /// IIdentity public virtual IIdentity GetCurrentUserIdentity() { return HttpContext.Current.User.Identity; } ///  /// Log the user in ///  /// User details public void LogIn(LoginUser user) { InvalidCredentialsOnNullUser(user); FormsAuthentication.SetAuthCookie(user.Name, false); } ///  /// Log the user out ///  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.... } 

La class LoginUser che vedi è informazione che viene recuperata su un utente di appartenenza. Questo è comunemente fatto tramite un MembershipProvider, ma naturalmente può essere fatto in altri modi.

 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; } 

Non sono sicuro di aver compreso correttamente la domanda, ma se ti stai riferendo a un modo per recuperare chi è l’utente corrente senza passarlo attraverso l’URL (ad esempio http: // localhost / controller / action? Username = RAMe0 ) allora tu può guardare usando Thread.CurrentPrincipal.Identity.Name o HttpContext.Current.User

Ci sono tuttavia sottili differenze tra i due. Guarda qui per maggiori dettagli.

Utilizzando FormsAuthentication è ansible memorizzare il nome utente nella proprietà User.Identity.Name . Ecco un semplice esempio di ciò che probabilmente stai cercando. (Usando lo stesso SetAuth che stai già utilizzando)

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

Questo non richiede il passaggio del nome utente tramite un parametro QueryString.