ASP.NET 在使用 Windows 身份验证和自定义角色提供程序时实现“充当”功能

Posted

技术标签:

【中文标题】ASP.NET 在使用 Windows 身份验证和自定义角色提供程序时实现“充当”功能【英文标题】:ASP.NET Implementing "Act As" functionality when using Windows Authentication and Custom Role Provider 【发布时间】:2012-06-05 20:54:36 【问题描述】:

我正在尝试为 ASP.NET 应用程序实现“充当”功能,同时使用 Windows 身份验证和自定义角色提供程序。基本上我想做的是:

使用 Windows Auth 获取当前用户的域帐户,以验证他们是已批准的域用户 使用自定义角色提供程序从 SQL Server 数据库获取权限信息。 实现功能以允许应用程序的管理员能够“充当”另一个用户,而无需他们以该用户的身份实际登录应用程序。

我试图实现的场景是应用程序管理员试图帮助用户解决问题并单击“充当”按钮以充当该用户并以他们看到的方式查看应用程序。因此,角色提供者需要了解当前用户正在充当其他人,并获取该用户而不是当前用户的权限信息。

我的计划是实现一个模拟功能,该功能将删除角色 cookie 并向会话变量添加一个值,指示该用户当前正在模拟另一个用户。但是,由于在授权发生时未填充会话,因此这是不可能的。我不想使用 cookie,因为我不希望这会导致管理员机器上的潜在持久状态(这样管理员无法打开应用程序的另一个窗口并充当另一个用户或查看他们自己的数据)。

鉴于会话不可用,我找不到保存“作为用户...”信息的好方法(没有 cookie)。我想使用角色提供者等,以便我可以利用 .NET 中的内置安全修整。这一切可能根本不可能,但我希望有人以前尝试过这个,或者对我可以尝试实施的事情提出建议。

提前致谢!!

【问题讨论】:

【参考方案1】:

查看我对类似问题的回答here

它的要点是:

我这样做的方式虽然有点粗鲁,但确实是有一个 我的数据库中包含登录名的模拟表 进行模拟的用户和他们的用户的登录 想冒充。

我添加了一些覆盖代码,以便当用户第一次访问 页面(它使用 Windows 身份验证),它将检查是否 用户在表中设置了模拟,然后放置此用户 ID 在处于会话状态的对象中。如果没有冒名顶替的话 会将实际的用户 ID 放在同一个对象中。

为了防止我像他们一样对用户的数据做事,有 此对象中有两个属性,一个用于 logon_name,它是什么 系统用于内容定制,另一个称为 NameForLog,用于记录任何操作。我做的所有动作 将被记录为我。

网站上显示用户自定义内容的所有区域 此会话对象,因此他们将始终使用模拟 ID 和 因此,请始终向我展示用户所看到的内容。超越第一 页面和日志代码,它甚至都不知道是我 处理。

对于您的场景,您可以实现一个角色提供程序并覆盖 GetRolesForUser 以返回模拟用户的角色以及一些允许模拟用户访问模拟功能以将其关闭的角色。

您甚至可以将模拟用户的角色与模拟用户的角色一起返回,以便让管理员用户能够访问他们自己的所有功能以及他们所模拟的用户,这完全取决于这会在多大程度上影响特定场景中的功能。

【讨论】:

感谢您的反馈,很抱歉长时间延迟回复。我知道我可以编写代码来解决这个问题,但我希望有一种方法我仍然可以利用内置的安全性,这样我就可以拥有所有的菜单和位置安全性,而不必输入自定义代码来处理那些碎片。从本质上讲,我希望我可以避免将自定义安全代码写入单个页面等,以解决这个问题,尽管这似乎不太可能。【参考方案2】:

我已经实现了类似的东西......虽然不完全像你的场景,但非常接近。

    管理员登录(有一个像管理员这样的角色)

    然后管理员被重定向到“选择客户端”页面。管理员可以按 ID、名称等搜索客户。管理员从列表中选择一个客户。我将客户端 ID 存储在 cookie 中。

    我有自定义 RolesProvider,它调用我的自定义 GetRoles(loggedinUserid)

    GetRoles(int loggedinUserId) 方法然后确定用户的类型,即它是管理员还是非管理员。如果是管理员,则从 cookie 中获取 ClientID。将 loggedInUserID、typdofuser 和 ClientId 传递给存储过程,该存储过程将返回 admin 的所有角色 + 该 ClientId 的所有角色并返回给角色提供者。

这样,我的所有 Admin 菜单项以及 ClientID 所需的菜单都可用。

管理员可以随时进入“选择客户端”页面并切换到另一个客户端。当他们选择一个客户端时,新的 ClientId 将被存储在 cookie 中。

在此之后您有两个选择:

    您可以让角色提供者在每次请求时调用它或

    将获取的角色存储在 HttpCache 中,并在 ClientId 更改时更新此缓存。

希望这会有所帮助。

【讨论】:

感谢您的反馈。我想我在问题中提到了 cookie 是我想要避免的东西,因为它们会比我想要的更持久。 IE。我不希望这个作为功能在浏览器窗口/会话中持续存在。我希望它只针对当前会话。管理 cookie 并不能完全达到我想要的效果。正如我在对另一个答案的评论中提到的那样,我很快意识到根本不可能避免为此进行页面级编码......这真的很愚蠢。 对于我的实现,我不必在每个页面上编写代码,但是我的自定义角色提供程序(即内置提供程序的再次扩展)会处理它。如果您不想使用 cookie,您可以在每个请求上使用 httpcache 或 db 调用...为什么?因为您将需要一种方法来跟踪管理员用户是否以自己的身份登录和/或还选择冒充为用户。此外,一旦管理员完成,他可以取消选择模拟。如果管理员更改用户,则需要更新角色。

以上是关于ASP.NET 在使用 Windows 身份验证和自定义角色提供程序时实现“充当”功能的主要内容,如果未能解决你的问题,请参考以下文章

具有 Windows 身份验证的 ASP .NET 身份和数据库中的角色

Windows 身份验证 Asp.net 知道如何

ASP.NET Core Windows 身份验证和应用程序角色

ASP.NET 2.0 中的 Windows 身份验证

ASP.NET Windows 身份验证仅提示一个用户的凭据

如何在 asp.net 中使用 Windows 身份验证获取用户名?