Authentication 使用身份验证的ASP.NET MVC 3

Authentication 使用身份验证的ASP.NET MVC 3,authentication,asp.net-mvc-3,Authentication,Asp.net Mvc 3,如何使用FormsAuthentication保存某些内容?我不想通过URL存储用户ID 例如,现在我有了以下代码: //UserController class: [HttpPost] public ActionResult LogOn(LogOnModel model, string returnUrl) { if (ModelState.IsValid) { if (repository.ValidateUser(model.Login, model.Password)) {

如何使用FormsAuthentication保存某些内容?我不想通过URL存储用户ID

例如,现在我有了以下代码:

//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();
}
ProjectsContext context=newprojectscontext();
UsersContext uCnt=新的UsersContext();
公共IEnumerable GetUserProject(字符串用户名)
{
if(String.IsNullOrEmpty(用户名))
抛出新的ArgumentNullException(“用户名”,“登录为空”);
返回this.uCnt.Users
.FirstOrDefault(u=>u.Login==用户名)
.项目
.ToList();
}
ProjectController和ProjectRepository看起来不是好代码。。。也许有人可以给出建议,如何在不使用URL的情况下存储用户ID?我认为最好的方法是在自动生成时保存ID。我在User.Identity中找不到任何属性来执行此操作

UPD 请原谅,我忘了说我正在使用MVC-3和Razor视图。
而且该UserId不是字符串(User.Identity.Name是字符串),它可能是GUID,也可能是我自己的对象…

我不确定我是否正确理解了这个问题,但如果您指的是一种检索当前用户的方法,而不必通过URL传递它(例如)然后可以查看如何使用Thread.CurrentPrincipal.Identity.Name或HttpContext.Current.User


然而,两者之间存在着微妙的差异。查看更多详细信息。

使用
表单身份验证
可以将用户名存储在
User.Identity.Name
属性中。这里有一个简单的例子,你可能正在寻找什么。(使用与您已经使用的相同的
SetAuth


这不需要您通过QueryString参数传入用户名。

为什么不先通过接口进行所有授权调用呢。这样,所有使用身份验证的代码都不需要关心如何执行登录,或如何存储标识等

public interface IAuthorization
{
    bool ValidateUser(LoginUser u, string password);
    LoginUser GetCurrentUser();
    void LogIn(LoginUser user);
    void LogOut();
    IIdentity GetCurrentUserIdentity();
}
IIdentity GetCurrentUserIdentity的实现可以是您喜欢的任何方式,但通常被视为对“HttpContext.Current.User.Identity”的调用


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

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);
您可以在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;
}
请注意,在本例中,CustomPrincipal派生自RolePrincipal(尽管如果您不使用角色,我认为您需要派生自GenericPrincipal),只需添加UserID属性并重载构造函数

现在,无论您在应用程序中何时需要用户ID,都可以执行以下操作:

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

隐马尔可夫模型。。。我在
HttpContext
中没有
当前的
成员。。。还有一件事:如果我重新加载页面,威尔从哪里来?但是steel I在
HttpContext
中没有当前的
Current
:(确保您有对System.Web.dll的引用,并且代码文件的顶部有“using System.Web;”关于不同之处的文章很好,但我没有意识到。这正是我正在做的…我想使用SetAuthCookie存储用户ID,也许还需要删除其他信息…最初的文章使用了接口方法,这就是为什么我复制了登录方法。我在意识到你是FormsService后重写了它。但我想真正关注的是第二个块使用
this.User.Identity.Name
。您可以始终在
User.Identity.Name
中存储更多信息(如果数据较短,则类似于json)。您也可以实现自己的
IIdentity
对象。您想基本上将所有用户信息存储在
user.Identity
中吗?从您的问题很难判断。我意识到……这是我的第一个问题,不像以前那样清楚……当您只存储和检查我们时,我不确定安全性er登录。所以我想在cookies中保存登录信息和密码。(可能还有一些附加信息)那就好了…后天我会试试。你在UserData中保存用户ID的第一部分似乎不完整。有人能解释或将代码包装到适当的类中,这样我就可以看到代码的位置了吗?谢谢。我不知道为什么还有人会想使用成员资格提供程序,自从它出现以来,它一直都是垃圾退出。角色由您自己授权。
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);
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;
}
if(HttpContext.Current.Request.IsAuthenticated)
    Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID;