ASP.NET MVC 3使用身份验证

RAM*_*Me0 22 authentication asp.net-mvc-3

如何使用FormsAuthentication保存内容?我不想通过URL存储UserId.

例如,现在我有这个代码:

//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);
}
Run Code Online (Sandbox Code Playgroud)

ProjectController 类:

public ViewResult Index()
{
    return View(repository.GetUserProjects(
        this.ControllerContext.HttpContext.User.Identity.Name));
}
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

ProjectController和ProjectRepository看起来不是很好的代码......也许有人可以提供建议,如何在不使用URL的情况下存储UserID?我认为,最好的方法是在autorisation上保存ID.我没有在User.Identity中找到任何属性来执行此操作...

UPD

请原谅,但我忘了说我正在使用带有Razor视图的MVC-3.而UserId不是一个字符串(User.Identity.Name是一个字符串)它可能是GUID或者我自己的对象...

The*_*man 38

当用户登录时,将UserID保存在授权cookie中的FormsAuthentication票证的UserData属性中:

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);
Run Code Online (Sandbox Code Playgroud)

您可以在Global.asax中的PostAuthenticateRequest方法中阅读它:

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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,从CustomPrincipal派生RolePrincipal(但如果你不使用的角色,我认为你需要从的GenericPrincipal派生),并简单地增加了UserID属性和过载的构造.

现在,无论您在应用中需要UserID,都可以执行以下操作:

if(HttpContext.Current.Request.IsAuthenticated)
    Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID;
Run Code Online (Sandbox Code Playgroud)

  • 多数民众赞成......我会在后天尝试. (2认同)

CRi*_*ice 5

为什么不先通过界面拨打所有授权电话.这样,所有使用身份验证的代码都不需要关心如何执行登录,或者如何存储Indentity等.

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

IIdentity GetCurrentUserIdentity的实现可以是你喜欢的任何方式,但通常被视为对"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....

}
Run Code Online (Sandbox Code Playgroud)

您看到的LoginUser类是检索有关成员资格用户的信息.这通常通过MembershipProvider完成,但当然可以通过其他方式完成.

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我不知道为什么有人仍然想要使用会员提供商,因为它出现以来一直是垃圾.角色你自己的身份证明. (4认同)
  • 这正是这个 (2认同)