ASP.NET MVC 如何使用 CookieAuthenticationMiddleware 在内部验证 Cookie

How is a Cookie validated internally by ASP.NET MVC using CookieAuthenticationMiddleware

我正在尝试弄清楚 ASP.NET 如何在内部验证 cookie 将允许用户访问应用程序。

CookieAuthenticationMiddleware 将设置 .AspNet.Cookies 为加密值。 .NET 根据请求成功解密 cookie 后,会发生什么验证?

如果我有一个在用户登录后设置身份验证 Cookie 的应用程序 (#1),则使用 IISExpress 在本地进行开发,并且我也在本地主机上 运行 创建了一个完整的新应用程序 (#2),即也在使用 CookieAuthentication。当我访问 #2 时,它将读取来自 #1 的 cookie,并允许用户也访问该应用程序。

我正在尝试了解 cookie 身份验证的限制。

主要验证是加密和过期。如果应用程序共享加密上下文(例如机器密钥),那么它们可以共享身份验证 cookie(前提是满足域和路径等其他客户端共享规则)。所以是的,在同一台机器上使用 IIS Express localhost 的两个应用程序默认会共享 cookie。

有效期也嵌入到加密值中,因此客户端无法篡改它。

实际上并没有 "validation" 本身。 cookie 的加密密钥用于引用应该是 "logged in" 的用户。它的工作方式与会话非常相似,其中会话 cookie 包含一个加密的会话 ID,服务器可以使用该 ID 来查找和恢复会话。

encryption/decryption基于机器密钥,可以在Web.config中明确设置,也可以由ASP.NET自动生成。只有共享相同机器密钥的应用程序才能解密 cookie,这就是保护您的机器密钥如此重要的原因。

无论如何,这里涉及两个因素。首先,cookie 是域绑定的:只有设置了 cookie 的域的域或子域才会被赋予 cookie。这是由客户端(即浏览器)处理的。您的两个应用程序目前都能够看到 cookie,因为它们都在本地主机上 运行。但是,如果您在 foo.com 部署一个,在 bar.com 部署另一个,那么它们将无法再看到彼此的 cookie。

其次,机器密钥通常由服务器提供(除非您在每个应用程序的 Web.config 中明确设置)。因此,同一台机器上的站点 运行 通常可以解密彼此的 cookie(假设他们首先看到它们,这又是基于他们的域)。

目前还不清楚您对这样的安排是否满意。如果您的目标是在本地隔离两个站点 运行,这样它们就不会共享 cookie,那么您有几个选择。

  1. 您可以在各自的 Web.config 文件中为每个站点明确设置 不同的 机器密钥。他们仍然会收到其他站点设置的任何 cookie,但他们将无法再解密它们,这基本上会导致它们被忽略。

  2. 您可以自定义身份验证 cookie 名称。您可以使用一个 .Site1.Auth 和另一个 .Site2.Auth 而不是使用默认的 cookie 名称。然后,即使任何一个站点也会收到另一个站点的 cookie,它也会简单地忽略它,因为它不是它的 auth cookie。

但是,如果您打算在生产中也依赖此行为(即您实际上 想要 登录到一个站点以登录到另一个站点) ,那么您需要在两个站点的 Web.config 文件中将机器密钥明确设置为 相同的 值。此外,您需要将它们部署在同一个域中,或者至少是该域的子域中。对于子域,您需要将 cookie 域设置为两者的通配符域 .mydomain.com。然后,您可以在 foo.mydomain.com 上设置一个,在 bar.mydomain.com 上设置另一个,他们都会看到 cookie,因为它是在 .mydomain.com 上设置的。如果您保留默认设置,在站点的实际域上设置,则 bar.mydomain.com 无法看到 foo.mydomain.com 设置的 cookie,因为该 cookie 将仅为 foo.mydomain.com 明确设置。