Pregunta

¿Cómo puedo ahorrar algo utilizando FormsAuthentication? No quiero para almacenar identificación de usuario a través de la URL.

Por ejemplo, ahora tengo este código:

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

clase 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<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 y ProjectRepository no se ve como un buen código ... Tal vez alguien puede dar consejos, cómo almacenar ID de usuario sin necesidad de utilizar la URL de? La mejor manera de hacer esto es guardar los ID de autorización es, creo. No se ha encontrado ningún propiedades en User.Identity hacer esto ...

UPD

Me pido perdón, pero se me olvidó decir que estoy usando MVC-3 con vistas Razor. Y que UserId no es una cadena (User.Identity.Name es una cadena) que podría ser GUID o tal vez mi propio objeto ...

¿Fue útil?

Solución

Guardar el ID de usuario en la propiedad UserData del billete FormsAuthentication en la cookie autorización cuando el usuario inicia sesión:

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

Se puede leer de nuevo en el método PostAuthenticateRequest en 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;
}

Tenga en cuenta que en este caso, se deriva de CustomPrincipal RolePrincipal (aunque si no se está usando Roles, creo que es necesario para derivar de GenericPrincipal), y simplemente añade la propiedad ID de usuario y las sobrecargas del constructor.

Ahora, siempre que se necesite la identificación de usuario en su aplicación, se puede hacer esto:

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

Otros consejos

¿Por qué no hacer primero todas sus llamadas de autorización a través de una interfaz. De esta manera todo el código que utiliza la autenticación no tiene que preocuparse acerca de cómo se realiza el inicio de sesión, o cómo se almacenan los Identity corporativos, etc.

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

Implemenation para la IIdentity GetCurrentUserIdentity podría ser lo que le gusta, pero es comúnmente visto como una llamada a "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....

}

La clase LoginUser que se ve es la información que se recupera de un usuario suscrito. Esto se realiza habitualmente a través de un MembershipProvider pero por supuesto se puede hacer de otras maneras.

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

No estoy seguro de entender la pregunta correctamente, pero si usted se refiere a una manera de recuperar que el usuario actual es, sin pasar a través de la URL (por ejemplo, http: // localhost / controlador / acción nombre de usuario = RAMe0 ) entonces se puede buscar en el uso Thread.CurrentPrincipal.Identity.Name o HttpContext.Current.User

Hay diferencias sutiles entre los dos, sin embargo. Mirada aquí para más detalles.

El uso de FormsAuthentication que puede almacenar el nombre de usuario en la propiedad User.Identity.Name. Aquí es un simple ejemplo de lo que es probable que busca. (Usando el mismo SetAuth ya está usando)

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

Esto no requiere que usted pase el nombre de usuario a través de un parámetro de cadena de consulta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top