ajax 设置 HttpContext.Current.User
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8704173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
setting HttpContext.Current.User
提问by Babak Fakhriloo
I am developing an asp.net mvc 3.0 application which has a simple authentication process. User fills a form which is sent to server by ajax call and gets response, but the problem here is that using the following method :
我正在开发一个具有简单身份验证过程的 asp.net mvc 3.0 应用程序。用户填写通过ajax调用发送到服务器的表单并获得响应,但这里的问题是使用以下方法:
FormsAuthentication.SetAuthCookie(person.LoginName,false);
is not enough to fill 'HttpContext.Current.User' and it needs the below method to be run :
不足以填充“HttpContext.Current.User”,它需要运行以下方法:
FormsAuthentication.RedirectFromLoginPage("...");
Problem here is that as i mentioned, the loggin form uses an ajax form, and get responses with json, so redirecting is not possible.
这里的问题是,正如我所提到的,登录表单使用 ajax 表单,并使用 json 获取响应,因此无法重定向。
How could I fill 'HttpContext.Current.User' ?
我怎么能填写 'HttpContext.Current.User' ?
Thanks.
谢谢。
Update :
更新 :
Here is register method :
这是注册方法:
[HttpPost]
public ActionResult Register(Person person)
{
var q = da.Persons.Where(x => x.LoginName == person.LoginName.ToLower()).FirstOrDefault();
if (q != null)
{
ModelState.AddModelError("", "Username is repettive, try other one");
return Json(new object[] { false, this.RenderPartialViewToString("RegisterControl", person) });
}
else
{
if (person.LoginName.ToLower() == "admin")
{
person.IsAdmin = true;
person.IsActive = true;
}
da.Persons.Add(person);
da.SaveChanges();
FormsAuthentication.SetAuthCookie(person.LoginName,false);
return Json(new object[] { true, "You have registered successfully!" });
}
}
回答by Luká? Novotny
FormsAuthentication doesn't support immediate setting of user's identity, but you should be able to fake it by something like this:
FormsAuthentication 不支持立即设置用户身份,但您应该能够通过以下方式伪造它:
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new System.Security.Principal.GenericIdentity(person.LoginName), new string[] { /* fill roles if any */ });
回答by Andrew Backer
Here is the version I ended up using, which is based on the answer by @AdamTuliper-MSFT. It is only meant to be used right after logging in, but before redirect, to allow other code to access HttpContext.User.
这是我最终使用的版本,它基于@AdamTuliper-MSFT 的答案。它仅意味着在登录后立即使用,但在重定向之前,以允许其他代码访问HttpContext.User.
- Don't do anything if already authenticated
- Doesn't modify the cookie, since this should only be used for the lifetime of this request
- Shorten some things, and a little safer with userdata (should never be null, but...)
- 如果已经通过身份验证,请不要做任何事情
- 不修改 cookie,因为这应该只用于此请求的生命周期
- 缩短一些东西,并使用 userdata 更安全一些(不应该为空,但是......)
Call this after you call SetAuthCookie(), like below:
在调用 SetAuthCookie() 之后调用它,如下所示:
// in login function
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
AuthenticateThisRequest();
private void AuthenticateThisRequest()
{
//NOTE: if the user is already logged in (e.g. under a different user account)
// then this will NOT reset the identity information. Be aware of this if
// you allow already-logged in users to "re-login" as different accounts
// without first logging out.
if (HttpContext.User.Identity.IsAuthenticated) return;
var name = FormsAuthentication.FormsCookieName;
var cookie = Response.Cookies[name];
if (cookie != null)
{
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null && !ticket.Expired)
{
string[] roles = (ticket.UserData as string ?? "").Split(',');
HttpContext.User = new GenericPrincipal(new FormsIdentity(ticket), roles);
}
}
}
Edit: Remove call to Request.Cookies, as @AdamTuplier-MSFT mentioned.
编辑:删除对 Request.Cookies 的调用,如@AdamTuplier-MSFT 所述。
回答by Adam Tuliper - MSFT
You need to manually set it. Rather than reinventing the wheel, note the section here on updating the current principal for the request - thats your option here.
您需要手动设置它。不要重新发明轮子,请注意此处有关更新请求的当前主体的部分 - 这是您的选择。
How to set Request.IsAuthenticated to true when not using FormsAuthentication.RedirectFromLoginPage?
不使用 FormsAuthentication.RedirectFromLoginPage 时如何将 Request.IsAuthenticated 设置为 true?
public void RenewCurrentUser()
{
System.Web.HttpCookie authCookie =
System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = null;
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && !authTicket.Expired)
{
FormsAuthenticationTicket newAuthTicket = authTicket;
if (FormsAuthentication.SlidingExpiration)
{
newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket);
}
string userData = newAuthTicket.UserData;
string[] roles = userData.Split(',');
System.Web.HttpContext.Current.User =
new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles);
}
}
}
}

