将 Forms 身份验证与 Windows 身份验证混合使用

Posted

技术标签:

【中文标题】将 Forms 身份验证与 Windows 身份验证混合使用【英文标题】:Mixing Forms authentication with Windows authentication 【发布时间】:2011-01-16 02:15:05 【问题描述】:

我有一个 (ASP.NET 3.5) Intranet 应用程序,它被设计为使用表单身份验证(以及默认的 aspnet 成员资格系统)。我还将有关用户的其他信息存储在另一个表中,该表与 aspnet_users 表共享其主键。

对于属于我们域的用户,我将他们的域帐户名存储在辅助用户表中,并且我想自动登录其域帐户名与存储在表中的名称匹配的用户。

我已阅读可用的指南 - 它们都来自两年或更长时间,并假设您能够在允许您提取域帐户名称的单独登录页面上激活 Windows 身份验证。不过,据我所知,这在 IIS7 中是不可能的(整体身份验证方法适用于所有页面,不能有选择地停用,两种身份验证方法不能应用于同一页面)。

有没有办法让 IIS 通过请求用户的 windows 域帐户名?我不需要正确的 AD 身份验证,只需要域名。

【问题讨论】:

【参考方案1】:

其实你可以的。 @dr_draik 有点晚了,但这突然出现在我的谷歌搜索结果中,所以我想我会分享一些知识。

如果您处于经典模式 - 启用 Windows 和 Forms 身份验证。您会收到无法同时执行这两项操作的警告,但您可以ignore it。然后,您可以探索各种属性,例如 代码:

HttpContext.Current.Request.ServerVariables["LOGON_USER"]

然后把用户名从那里捞出来。

如果您处于集成模式 - 4021905 IIS7 Challenge-based and login redirect-based authentication cannot be used simultaneiously 会引导至 IIS 7.0 Two-Level Authentication with Forms Authentication and Windows Authentication,这是一个允许您有选择地更改不同页面的身份验证的模块。

【讨论】:

切换接受的答案,因为显然这个问题得到了很多点击,这样会更清楚。 集成模式的解决方案不适用于 .NET 4.5 和 IIS8。有人破解了吗? 我禁用了 Windows 身份验证,只使用表单身份验证,这个 HttpContext.Current.Request.ServerVariables["LOGON_USER"] 仍然有效。我需要这样做,因为有时我们的用户需要能够从他们的 Windows 帐户中注销并使用其他凭据登录。我注意到如果启用了 Windows 身份验证,那么在用户切换帐户后它将不会使用新的表单用户 ID。 如何禁用windows身份验证?在 IIS 中?并使用 ASP.NET Core ?并使用 Powershell ?【参考方案2】:

您总是可以在 IIS7 中设置 2 个单独的应用程序。一种是启用 Windows 身份验证。另一个是带有表单身份验证的主应用程序。如果用户访问 Windows 身份验证应用程序,该页面可以获取他们的凭据并将其传递给表单身份验证应用程序。

【讨论】:

谢谢,这两个应用程序解决方案似乎是最可行的,但我认为我们只需要使用表单身份验证。一个单独的应用程序只用于登录感觉相当笨拙。 “该页面可以获取他们的凭据并将其传递给表单身份验证应用程序”这是我不明白的部分......如何传递它?【参考方案3】:

(为了信息的完整性,更多信息真的)

我在不久前的一次会议上向 .Net 安全人员询问了这个问题。他的回答是技术上是可能的,但他从未见过它完成(如果我做了它并且让他知道它是否有效!)。

他建议可以通过制作自己的 ISAPI 过滤器并将其安装到 IIS 中来完成。 ISAPI 过滤器将拦截请求并基本上完成 IIS 在使用集成身份验证时所做的工作,但如果不存在,则回退到使用表单。这涉及过滤器中一些复杂的挑战/响应逻辑。不过这是针对 IIS6 的,所以在 IIS7 中可能会有所不同。

虽然这在技术上可能是可行的,但我不建议这条路线,因为这感觉有点像 hack,并且自行部署安全性从来都不是一个好主意(除非你 真的知道你在做什么)。

【讨论】:

感谢您的意见 - 这不再可能(或实际上不再可能)有点烦人,但我想这是进步的代价。 感谢您分享此信息!我同意你所说的,除非我们非常确定,否则不要推出我们自己的安全功能【参考方案4】:

有很多关于通过将配置设置为使用允许匿名访问应用程序的表单来混合身份验证的文章。其次,应创建一个集成身份验证页面,并将 IIS 设置设置为拒绝匿名并使用集成身份验证。在那里,您可以通过检查 requets 的 ServerVariables 集合的“Logon_User”变量来获得魔术。最后,对于集成身份验证以静默方式登录用户,它必须具有简短的托管名称。因此,如果您的表单身份验证部分通过 FQDN 暴露在互联网上,则应该有某种重定向到短主机页面。我认为可以通过 IIS 下的一个具有 2 个虚拟目录的应用程序来实现。

【讨论】:

据我所知,此解决方案适用于 IIS6,但不适用于 IIS7。这是因为在 IIS6 中,您可以在每个文件夹(甚至每个文件)的基础上分配身份验证模式,而在 IIS7 上,身份验证设置对整个应用程序都是全局的。【参考方案5】:

我找到了一个不使用特殊插件的解决方案。这很棘手,涉及将此处引用的所有页面中的元素拼凑在一起。 我发布了它:http://low-bandwidth.blogspot.com.au/2014/11/iis7-mixed-windows-and-forms.html

本质上,必须启用表单、窗口和匿名身份验证。 登录屏幕应该是基于表单的,并包含一个触发 Windows 登录的按钮,该按钮会发出 HTTP 401 响应质询,如果成功则创建基于表单的登录票。

问题比较复杂,帖子里有详细的原理和解决方法。

【讨论】:

【参考方案6】:

很遗憾,您尝试执行的操作不受支持。为了让 ASP.NET 知道 Windows 用户名,您必须使用 Windows 身份验证。

您可以设置另一个站点/虚拟目录,将用户名信息转发到另一个页面。但是当非 Windows 身份验证的用户尝试登录时会发生什么?

【讨论】:

谢谢,这两个应用程序解决方案似乎是最可行的,但我认为我们只需要使用表单身份验证。一个单独的应用程序只用于登录感觉相当笨拙。【参考方案7】:

我有一些你可以尝试的东西 - 不确定它是否会起作用。

过去我们使用过Request.ServerVariables["LOGON_USER"],但显然要返回一个非空值,您需要禁用匿名访问。

见这篇文章:http://support.microsoft.com/default.aspx/kb/306359

建议在 IIS 端保持匿名访问,以及 Forms 身份验证,但拒绝匿名用户如下:

<authorization>
   <deny users = "?" /> <!-- This denies access to the Anonymous user -->
   <allow users ="*" /> <!-- This allows access to all users -->
</authorization>

【讨论】:

谢谢 - 试一试,但即使按照推荐的设置,它仍然是一个空字符串。我仔细检查了这篇文章,不幸的是,它不适用于 IIS7。

以上是关于将 Forms 身份验证与 Windows 身份验证混合使用的主要内容,如果未能解决你的问题,请参考以下文章

在 Chrome 上弹出处理 windows 身份验证

经典FormsAuthenticationTicket 分析

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

ASP.NET Windows 和窗体身份验证

asp.net Forms身份验证详解

我可以提供触发 Windows 身份验证的链接吗?