我有一个网站,我允许一些用户作为其他用户代理。当他们这样做时,他们应该看到整个网站就像他们代理的用户所在。我这样做是通过更改当前用户对象
internal static void SetProxyUser(int userID)
{
HttpContext.Current.User = GetGenericPrincipal(userID);
}
此代码适用于我。
在网站上,要代理,用户选择我在_layout文件中呈现的下拉列表中的值,以便它显示在所有页面上。
@Html.Action("SetProxyUsers", "Home")
SetProxyUsers视图如下所示:
@using (@Html.BeginForm("SetProxyUsers", "Home")) {
@Html.DropDownList("ddlProxyUser", (SelectList)ViewBag.ProxyUsers_SelectList, new { onchange = "this.form.submit();" })
}
此操作的控制器操作如下所示
[HttpGet]
public ActionResult SetProxyUsers()
{
ViewBag.ProxyUsers_SelectList = GetAvailableProxyUsers(originalUserID);
return PartialView();
}
[HttpPost]
public ActionResult SetProxyUsers(FormCollection formCollection)
{
int id = int.Parse(formCollection["ddlProxyUser"]);
RolesHelper.SetProxyUser(id);
ViewBag.ProxyUsers_SelectList = GetAvailableProxyUsers(originalUserID);
return Redirect(Request.UrlReferrer.ToString());
}
这一切都有效(除了originalUserID变量之外,我在这里设置了象征我接下来要做的事情。
我的问题是下拉列表中的值基于登录用户。因此,当我使用代理更改用户时,我还会更改代理下拉列表中的值(如果不允许“新”用户代理则消失,或者显示“新”用户的可用代理用户列表)。
我需要让这个选择列表保持不变。如何存储原始用户的ID?我可以将它存储在一个会话变量中,但我不想搞砸潜在的超时问题,所以这是最后的手段。
请帮忙,如果对此问题有任何疑问,请告诉我。
更新
我没有意识到为每个帖子设置了HttpContext
。我以前没有真正使用过这种东西,并且出于某种原因假设我正在设置整个会话的值(愚蠢,我知道)。但是,我正在使用Windows身份验证。如何更长久地更改用户(只要浏览器打开)?我假设我不能使用FormAuthentication cookie,因为我使用Windows作为我的身份验证模式,对吗?
答案 0 :(得分:2)
不是伪造身份验证,为什么不让它真实?在我工作的网站上,我们让管理员通过为用户设置身份验证cookie来模拟其他用户。然后原始用户ID存储在会话中,因此如果他们从模拟用户帐户注销,他们实际上会自动重新登录到其原始帐户。
修改强>:
这是我如何模仿的代码示例:
[Authorize] //I use a custom authorize attribute; just make sure this is secured to only certain users.
public ActionResult Impersonate(string email) {
var user = YourMembershipProvider.GetUser(email);
if (user != null) {
//Store the currently logged in username in session so they can be logged back in if they log out from impersonating the user.
UserService.SetImpersonateCache(WebsiteUser.Email, user.Email);
FormsAuthentication.SetAuthCookie(user.Email, false);
}
return new RedirectResult("~/");
}
简单就是这样!它一直很好用。唯一棘手的部分是存储会话数据(这当然不是必需的,它只是提供给我的用户的一个很好的功能,所以他们不必一直重新登录)。我正在使用的会话密钥是:
string.Format("Impersonation.{0}", username)
其中username
是被模拟用户的名称(该会话密钥的值是原始/ admin用户的用户名)。这很重要,因为当注销发生时,我可以说,"嘿,你有没有假冒的钥匙?因为如果是这样,我将以会话中存储的用户身份登录。如果没有,我会告诉你"。
这是LogOff方法的一个示例:
[Authorize]
public ActionResult LogOff() {
//Get from session the name of the original user that was logged in and started impersonating the current user.
var originalLoggedInUser = UserService.GetImpersonateCache(WebsiteUser.Email);
if (string.IsNullOrEmpty(originalLoggedInUser)) {
FormsAuthentication.SignOut();
} else {
FormsAuthentication.SetAuthCookie(originalLoggedInUser, false);
}
return RedirectToAction("Index", "Home");
}
答案 1 :(得分:0)
我在本文http://www.codeproject.com/Articles/43724/ASP-NET-Forms-authentication-user-impersonation至
的评论中使用了mvc示例它使用FormsAuthentication.SetAuthCookie()来更改当前授权的cookie,并将模拟的用户身份存储在cookie中。这样,它可以轻松地将您重新验证回原始用户。
我很快就开始工作了。使用它可以让管理员像其他人一样登录。