将用户的 Active Directory 凭据发送到后端系统是不是错误

Posted

技术标签:

【中文标题】将用户的 Active Directory 凭据发送到后端系统是不是错误【英文标题】:Is it wrong to send Active Directory credentials of a user to a backend system将用户的 Active Directory 凭据发送到后端系统是否错误 【发布时间】:2020-11-12 18:11:19 【问题描述】:

我今天不得不查看一个 Intranet 站点的一些代码,它是一个带有 C# WebAPI 的 javascript 表单,它将 AD 用户名和密码(在登录期间)发送到后端,然后以该用户身份登录到 AD 以检查有效性。 (这都是本地的)。

我的 cmets 认为这相当于制作一个带有 facebook 徽标以及用户名和密码的表单,并要求用户使用它登录您的网站,然后自己登录 facebook 以检查 facebook 凭据是否有效。所以钓鱼和中间人一样,如果我们在我们的 Web 应用程序中拥有所有用户的所有 AD 凭据,那么就可以在任何地方以该用户身份登录并执行所有操作。

但是...讨论从开发团队开始,争论是

    它可以工作,为什么不呢(没有什么可以出错的,它是 Intranet) 示例也在 stackexchange 上,例如这里: Validate a username and password against Active Directory?) 。因此,对于这个例子,我假设这仅用于特定情况,但从不在网络案例中使用 当您使用某种语言编写桌面应用程序时,您还需要以某种方式验证自己是否能够抵御 AD。 这是模拟的完美示例:我们模拟每个用户(我会在How to pass Windows Authentication credential from client to Web API service 的行中考虑更多) 如果我们将程序扩展为用户可以更改其广告密码的点,我们将需要新密码(和域管理员凭据),所以这相同(我认为您将始终重置等)

所以这会带来疑问。我的想法是(显然对于 AD 而不是 ADFS)

Windows 中的用户登录 用户打开浏览器访问 URL IIS 配置了一个启用了 Windows 身份验证的站点 浏览器和 IIS 进行协商(浏览器与 Windows 层通信) 用户是否有效>继续

据我所知,这是最佳实践(stackexchange 上的大量链接,例如 proper implementation of "windows" authentication in web api? 和网络,例如 https://support.microsoft.com/en-us/help/323176/how-to-implement-windows-authentication-and-authorization-in-asp-net)

【问题讨论】:

请注意,在这里征求意见是题外话。但是,如果您需要对用户进行身份验证,您还会做什么?这里没有。 我在大约 3000 万个站点上添加了关于 Windows 身份验证和 iis 的最佳实践。 【参考方案1】:

应用程序不应该能够拦截用户密码。

因此,现代 Web 和移动应用程序将身份验证过程与 SAML IdP 或 OAuth2 授权服务器/OpenID 提供程序分开。

如果客户端和应用程序都已加入域,则本机 Windows 应用程序可以使用 Kerberos。

所有上述技术使应用程序能够获得经过验证的用户身份,同时无需将用户名和密码直接传输到应用程序。

【讨论】:

【参考方案2】:

这相当于制作一个带有 facebook 徽标以及用户名和密码的表单,并要求用户使用它登录您的网站,然后自己登录 facebook

由于信任问题,这不是一个准确的类比。你的公司不是 Facebook。

您的应用程序要求您公司的员工提供您公司内部 Active Directory 的凭据。那里有信任。这更像是一个由 Facebook 运营的网站,要求您提供 Facebook 凭据。

这并不是说没有安全问题。 Windows 身份验证是最好的方法,不仅因为您不与任何其他应用程序共享密码,而且因为它易于使用。如果设置正确,用户无需输入用户名和密码即可自动登录。这会让用户感到满意。

但是,如果您需要对外部域进行身份验证,这将不起作用。这就是我设置登录表单以收集 AD 用户名和密码的地方。我们的几个网站需要允许来自外部 AD 域的用户登录(没有 AD 信任),所以我通过 HTTPS 获取用户名和密码,并通过 LDAPS 对外部域进行身份验证。但是,我们不存储密码。一旦我们使用外部域验证了凭据,我们就会使用用户名创建表单身份验证令牌,然后忘记密码。

如果您将 AD 密码存储在自己的数据库中,那么我认为这是最大的问题。如果有人拥有该数据库,那么您的所有用户都可以在您组织的其他任何地方被冒充。

【讨论】:

在我们的案例中,我们为公司提供仅本地解决方案。所以我们要求公司相信我们不会用他们用户的 AD 凭证做坏事。由于代码已关闭。总体而言,我认为您是在说,因为例如登录到外部域,您需要凭据存在这些情况。然后可以将其扩展到为什么不将其用于内部和外部域以使一个组件通用地处理此问题。反对这一点的论点是,Windows 身份验证的自动单点登录更加用户友好。 (因此就“信任”而言,我们的应用程序在您的公司内部运行,但不属于您的公司) 它是第 3 方软件这一事实稍微改变了一些情况,但这仍然取决于每个公司的决定。获取用户名和密码并通过 LDAP 进行身份验证仍然很常见——只要它不存储密码。 Windows 身份验证对用户更友好,但在这种情况下也更安全。我们首先尝试 Windows 身份验证,然后仅在失败时回退到登录页面。我在不久前的另一个答案中描述了我是如何做到这一点的:***.com/a/62219205/1202807

以上是关于将用户的 Active Directory 凭据发送到后端系统是不是错误的主要内容,如果未能解决你的问题,请参考以下文章

用户需要哪些权限来验证 Active Directory 中的凭据?

使用 AD 的服务帐户和用户帐户凭据连接到 Active Directory 以登录(在我的产品中)

无需硬编码用户名/密码即可更新 Active Directory

通过 Spring Security 的 Active Directory 身份验证返回由 LDAP 引起的有效用户的错误凭据:错误代码 49

通过spring security进行的Active Directory身份验证会返回由LDAP引起的有效用户的错误凭据:错误代码49

为啥 Active Directory 验证最后一个密码?