Frage

Wie kann ich speichern etwas mit FormsAuthentication? Ich will nicht, Benutzer-ID durch URL speichern.

Zum Beispiel, jetzt habe ich diesen Code ein:

//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 Klasse:

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 und ProjectRepository Sie sieht nicht wie ein guter Code ... Vielleicht hat jemand Beratung geben kann, wie Benutzer-ID zu speichern, ohne URLs zu verwenden? Der beste Weg, dies zu tun speichern IDs auf autorisation ist, glaube ich. Ich fand keine Objekte in User.Identity, dies zu tun ...

UPD

ich bitte eine Begnadigung, aber ich vergessen zu sagen, dass ich mit MVC-3 mit Razor Ansicht. Und die Benutzer-ID ist kein String (User.Identity.Name ist ein String) es GUID sein könnte oder vielleicht mein eigenes Objekt ...

War es hilfreich?

Lösung

Speichern Sie die Benutzer-ID in der Userdata-Eigenschaft des FormsAuthentication Ticket in der Genehmigung Cookie, wenn sich der Benutzer anmeldet:

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

Sie können es zurück in der PostAuthenticateRequest Methode in Global.asax lesen:

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

Beachten Sie, dass in diesem Fall ergibt sich aus Customroleprincipal (obwohl, wenn Sie nicht Rollen verwenden, ich glaube, Sie müssen von Generic abzuleiten) und fügt einfach die UserID-Eigenschaft und Überlastungen der Konstruktor.

Jetzt, wo Sie die Benutzer-ID in Ihrer Anwendung benötigen, können Sie dies tun:

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

Andere Tipps

Warum nicht zuerst alle Ihre Genehmigung machen Anrufe über eine Schnittstelle. Auf diese Weise alle Ihre Codes, die Authentifizierung verwendet muss nicht besorgt sein, wie die Anmeldung durchgeführt wird, oder wie die Indentity gespeichert ist, etc.

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

Implemenation für die IIdentity GetCurrentUserIdentity könnte eine Möglichkeit sein, die Sie mögen, aber wird allgemein als Aufruf zu „HttpContext.Current.User.Identity“

gesehen
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....

}

Die Loginuser Klasse, die Sie sehen, sind Informationen, die über eine Mitgliedschaft Benutzer abgerufen wird. Dies wird im Allgemeinen über eine MembershipProvider gemacht, aber natürlich können auch andere Arten erfolgen.

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

Ich bin nicht sicher, verstehe ich die Frage richtig, aber wenn Sie auf eine Art und Weise Bezug zum Abrufen, die der aktuelle Benutzer ohne es durch die URL übergibt (zB http: // localhost / controller / action username = RAMe0 ), dann können Sie Thread.CurrentPrincipal.Identity.Name oder HttpContext.Current.User schauen mit

Es gibt subtile Unterschiede zwischen den beiden jedoch. Schauen Sie hier für weitere Details.

FormsAuthentication verwenden können Sie speichern den Benutzernamen in der User.Identity.Name Eigenschaft. Hier ist ein einfaches Beispiel dafür, was Sie wahrscheinlich für suchen. (Unter Verwendung des gleichen SetAuth Sie bereits verwenden)

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

Dies bedeutet nicht, dass Sie benötigen den Benutzernamen in durch eine Abfrage-Zeichenfolge-Parameter zu übergeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top