如何通过LDAP的控制器使用ASP.NET模拟

本文关键字:ASP NET 模拟 控制器 何通过 LDAP | 更新日期: 2023-09-27 18:22:14

我读过很多类似于我的问题的SO问题,但似乎没有什么能同时触及所有问题。

我有一个使用Windows身份验证的ASP.NET MVC应用程序,应用程序池标识设置为专用服务帐户。这允许我们使用WindowsPrincipal根据我们的系统角色对用户进行身份验证,但让任何外部系统(即数据库)仅根据服务帐户对我们的应用程序进行身份验证。

在我们想将数据更改推送到用户的AD帐户之前,一切都很好,因为公司的政策是,我们必须作为经过身份验证的用户这样做,但我们显然没有用户的密码才能使用DirectoryEntry重载。

在这种情况下,以下返回一个有效的DirectoryEntry实例,但CommitChanges抛出UnauthorizedAccessException"拒绝访问"。即使当前标识(在Thread.CurrentPrincipal和请求上)是当前用户模拟级别模拟

using (var de = new DirectoryEntry("LDAP://" + userPath))
{
    de.Properties["telephoneNumber"].Value = phone;
    de.CommitChanges();
}

我还尝试过在用户的WindowsIdentity上使用HostingEnvironment.ImpersonateWindowIdentity。ImpersonateirectoryEntry,其中DirectoryServicesOMException"发生操作错误"。

例如(不是实际代码),

using (var hei = System.Web.Hosting.HostingEnvironment.Impersonate(wi.Token))
using (var de = new DirectoryEntry("LDAP://" + userPath));

WindowsImpersonationContext ctx = wi.Impersonate();
using (var de = new DirectoryEntry("LDAP://" + userPath));

据我所知,LDAP不支持这种类型的模拟。

我能够使其工作的唯一方法(仅限于我自己)是为自己设置应用程序池标识,证明LDAP代码是正确的,但这并不能让我更接近如何正确地进行身份验证。我试过<identity simulate="true"/>(我们通常将其设为false),但它并没有改变任何内容。

任何指导都将不胜感激,因为我已经没有什么可调整的了。


编辑一些额外的上下文

几乎是TL;DR:

这是一项新功能,因此系统在通过IIS对用户进行身份验证方面按预期工作。我们获取用户的有效WindowPrincipal和WindowsIdentity。

我们的用户可以修改AD中的某些字段,如"telephoneNumber",因此我们无法访问(因为我们不需要)用于更改用户的特权帐户
如果我将所有内容都设置为自己,我可以更改自己的AD数据,但当应用程序以服务帐户(甚至匿名)运行时,我无法进行模拟。

如何通过LDAP的控制器使用ASP.NET模拟

据我所知,AD不允许用户修改目录服务信息,无论该信息是否为用户自己的帐户。您必须使用具有提升权限的帐户才能执行此操作(我不确定确切的权限,可能是域管理员)。

如果您希望用户能够修改他们自己的目录服务属性,那么您必须将该信息传递给在提升权限下运行的服务。

如果这是用于身份验证,则需要使用LogonUser来获取令牌,然后将WindowsIdentity与该令牌一起使用。但请记住,要模拟用户,您需要一个未复制的令牌。为了获得他们的用户名/密码,您需要编写一个通过HTTPS使用基本身份验证的自定义身份验证提供程序。(参见IHttpModule)和事件AuthenticateRequest进行身份验证并检查WWW-authenticate标头,EndRequest在必要时发出质询,PostRequestHandlerExecute在必要时修改cookie。

编辑:如果我还没有解决你的问题,请告诉我。我不确定您在模拟用户帐户时是否在验证用户身份或修改其帐户属性时遇到问题。

此外,您的web.config是否设置为

<identity impersonate="true" />

我最近遇到了同样的问题,最终能够让它正常工作。缺少的设置是Kerberos委派,类似于这里的场景1:https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/configure-kerberos-constrained-delegation

Windows身份验证协商是实际上涵盖两种独立身份验证机制的术语:Kerberos和NTLM。两者都被认为是";Windows";auth,因为它们使用用户的AD凭据进行身份验证,而不需要向服务器发送明文密码。协商是指客户端和服务器就使用Kerberos还是NTLM进行协商。Kerberos是首选,但在许多情况下需要额外的设置。如果尚未执行该设置,则将使用NTLM。只有Kerberos能够进行此处尝试的那种委派,因此需要正确设置Kerberos。

简而言之,要做到这一点,需要以下几点:

  • 将服务主体名称设置为";HTTP/<WebAppHostname>quot;在AD中的服务帐户上
  • 将服务帐户配置为能够将身份验证委派给AD服务器。这是在服务帐户的AD对象的委派选项卡上完成的。
    • 选择";允许委派到任何服务"
    • 选择";"允许委派到指定的服务";,然后选择";LDAP/<域控制器主机名>quot;对于环境中的每个域控制器

或者,如果web应用程序可以使用基本身份验证,这些问题应该会消失WindowsIdentity。在这种情况下,模拟应该可以在没有任何Kerberos设置的情况下工作。除了打开基本

外,只需确保关闭Windows auth