【问题标题】:Allow Administrators to impersonate users using an iframe允许管理员使用 iframe 模拟用户
【发布时间】:2013-08-02 19:04:38
【问题描述】:

我有一个具有三个角色的 MVC 项目:用户、客户经理和管理员。

管理员有自己的 MVC 区域,他们可以完全控制用户和客户经理。我正在尝试实现允许管理员以任何用户或客户经理的身份查看网站的功能。

在站点的管理区域,我有一个用户和客户经理列表的视图。该列表包含每条记录的“以用户身份查看站点”按钮。

我以前从未做过这样的事情,但 ViewAs 控制器操作当前已设置为使用所选用户的信息创建一个会话,如下所示:

ViewBag.SiteSession = Session["SiteSession"] = new SiteSession()
{
    ID = user.ID,
    AccountID = user.AccountID,
    DisplayName = user.DisplayName,
    IsManager = user.IsAdmin,
    IsAdmin = false
};

与此操作相关的视图将模型定义为string,除了一个将模型定义为src 属性的 iframe,如下所示:

@model string
<iframe src="@Model" >

</iframe>

我要做的是呈现此 iframe 中请求的网站的任何部分。当管理员单击“以用户身份查看”时,我想定向到主页。该 URL 是通过此调用生成的:

Url.Action("Index", "Home", new { Area = "" }));

为了避免渲染管理区域的主页,区域设置为空。

目前,这不起作用。我什至不知道从哪里开始,减去我已经拥有的。

我正在寻找任何建议。非常感谢所有帮助,因为这似乎不是一件容易的事。

如果您不知道如何提供帮助,如果您能将这个问题发给能够提供帮助的人,我们将不胜感激。

再次感谢您。

【问题讨论】:

    标签: asp.net-mvc-4 model-view-controller iframe admin


    【解决方案1】:

    我过去这样做的方式是使用实际用户和有效用户的概念。大多数显示操作使用有效用户来生成他们的内容。通常,我将其实现为“模拟”而不是“预览”,因此用户实际上是以用户身份浏览网站,而不是在单独的窗口中显示。在这种情况下,我只是在当前会话中设置两者。需要管理员权限的事情(例如切换到/从模拟)显然使用真实用户。

    如果您想进行预览,那么我会考虑在每个请求上使用一个参数来设置有效用户。代码需要理解才能将此参数添加到所有链接,以便您可以在iframe 中导航,而不会弄乱原始界面中的导航。

    至于从 url 中删除该区域,我认为您所拥有的(设置为空字符串)应该可以工作。如果它不起作用,您可能想尝试小写areaUrl.Action("Index", "Home", new { area = "" })。不过,我很确定在后台创建的 RouteValueDictionary 使用了不区分大小写的键比较,所以这无关紧要。

    【讨论】:

    • 我将其称为“预览”,因为您在 iframe 中单独显示,同时保持原始界面不变。也许我的术语是错误的,但我所说的模拟是指您只需更改原始界面以显示为模拟用户(唯一的区别是停止模拟的能力)。并排模拟似乎更难,因为在没有请求参数的情况下,服务器上无法区分来自 iframe/封闭窗口的请求。
    【解决方案2】:

    对于这项任务,我最终创建了一个单独的控制器 ViewAsController,它具有控制器范围的 [Authorize] 属性,仅允许具有 Admin 角色的用户访问其操作。

    Start 操作中,会创建一个包含所选用户信息的Session 对象,如下所示:

    [HttpGet]
    public ActionResult Start(int id)
    {
        var user = db.Users
            .First(u => u.ID == id);
    
        Session["SiteSession"] = new SiteSession()
        {
            //Session data...
        };
    
        return PartialView("_IFrame");
    }
    

    此操作返回一个部分视图,我最终显示在一个 jQuery UI 模式对话框窗口中。

    这是部分视图的代码:

    @{
        ViewBag.SiteSession = (SiteSession)Session["SiteSession"];
    }
    <h2>Viewing Site As @ViewBag.SiteSession.DisplayName</h2>
    <div>
        <iframe src="@Url.Action("Index", "Home", new { Area = "" })"></iframe>
    </div>
    

    如您所见,它非常裸露,而这正是它所需要的。 &lt;iframe&gt; 充当浏览器中的浏览器,允许管理员用户完全访问所选用户将执行的任何操作。

    为了详细起见,这里是创建对话框并打开它的 jQuery:

    $(function () {
        $("#viewAsDialog").dialog({
            modal: true,
            autoOpen: false,
            resizable: true,
            draggable: true,
            closeOnEscape: false,
            height: $(window).height() * .9,
            width: 1000,
            closeText: '',
            close: function () {
                $.post("@Url.Action("End", "ViewAs", new { Area = "Admin" })")
                        .success(function (result) {
                        });
            }
        });
    });
    
    function viewAs(result) {
        $("#viewAsDialog").html(result);
        $("#viewAsDialog").dialog("open");
    }
    

    您可以在此处看到该对话框已在文档就绪时初始化,并且在成功完成检索局部视图的 AJAX 调用之前不会打开。

    一旦管理员关闭对话框,服务器就会调用 ViewAs 控制器中的 End 操作,从而销毁会话:

    [HttpPost]
    public ActionResult End()
    {
        Session["SiteSession"] = null;
    
        return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 2014-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多