使用 Microsoft 登录
登录或创建帐户。
你好,
使用其他帐户。
你有多个帐户
选择要登录的帐户。

ASP .NET 支持语音列

表单身份验证疑难解答

欢迎使用“ASP.NET 支持语音”列! 我叫杰里·奥曼 我在 Microsoft 工作了 5 年多,大部分时间都专注于与 Web 相关的技术,如 Microsoft FrontPage 和新的 Microsoft SharePoint 技术。 在过去的一年里,我一直在 Microsoft ASP.NET 担任支持工程师。 本月,在“支持语音”列中,我将说明如何在 Microsoft ASP.NET 中排查表单身份验证问题。

表单身份验证疑难解答

在 ASP.NET 应用程序中使用 Forms 身份验证时,你可能会发现有必要排查用户随机重定向到登录页时出现的问题。 在理想情况下,此问题的发生方式使你能够轻松附加调试器并捕获问题。 但在生产环境中,这种情况很少出现。 若要排查此类随机问题,需要记录与问题相关的信息,以便缩小根本原因的范围。

在本专栏中,我们将简要介绍窗体身份验证概念。 然后,我们将了解哪些方案会导致用户重定向到登录页,以及如何捕获与隔离问题相关的数据。 我们还介绍如何实现 IHttpModule 接口来记录 Forms 身份验证信息。

Forms 身份验证概述

当用户使用表单身份验证向网站进行身份验证时,服务器会创建一个 Cookie。 Cookie 的值是加密表单身份验证票证。 每次请求应用程序时,Cookie 都会传递给服务器,FormsAuthenticationModule 类解密 Cookie 值并确定用户是否有效。

默认情况下,FormsAuthenticationModule 类添加到 Machine.config 文件中。 FormsAuthenticationModule 类管理 FormsAuthentication 过程。

下面是 Machine.config 文件中的条目:

<httpModule>
     …other modules…
     <add name="FormsAuthentication"
         type="System.Web.Security.FormsAuthenticationModule" />
     …other modules…
</httpModule>

使用表单身份验证进行身份验证的常规 HTTP 流量如下所示:

  1. 客户端将 HTTP GET 发送到 Default.aspx。 不会发送表单身份验证 Cookie。

  2. 服务器发送 302 响应 (重定向) 到 Login.aspx。

  3. 客户端将 HTTP POST 发送到 Login.aspx。 它包括登录信息。

  4. 服务器发送 302 响应 (重定向) 到 Default.aspx。 包含表单身份验证 Cookie。

  5. 客户端将 HTTP GET 发送到 Default.aspx。 这包括表单身份验证 Cookie。

有关实现和使用表单身份验证的详细信息,请访问以下 MSDN 网站:

http://msdn2.microsoft.com/en-us/library/7t6b43z4.aspx

http://msdn2.microsoft.com/en-us/library/system.web.security.formsauthentication (vs.71) .aspx

http://msdn2.microsoft.com/en-us/library/system.web.security.formsauthenticationticket (vs.71) .aspx有关共享表单身份验证 Cookie 的详细信息,请访问以下 ASP.NET 网站:

http://quickstarts.asp.net/QuickStartv20/aspnet/doc/security/formsauth.aspx

用户可能重定向到登录页的原因

表单身份验证 Cookie 丢失

情形 1


在此方案中,用户登录到网站。 在某个时候,客户端向服务器发送请求,并且
FormsAuthenticationModule 类不接收 Cookie。 可以通过在 IIS) Microsoft Internet Information Services (中启用 cookie 日志记录来确定用户请求是否不包含 Cookie。 为此,请执行以下步骤:

  1. 打开 IIS Microsoft 管理控制台 (MMC) 。

  2. 右键单击网站,然后单击“
    属性”。

  3. 单击“ 网站 ”选项卡,然后单击“ 启用日志记录”。

  4. 确保日志格式为 W3C 扩展日志文件格式

  5. 单击“ 属性”。

  6. 单击“ 高级 ”选项卡,然后单击“
    扩展属性”。

  7. 在“扩展属性”下,单击以选中“Cookie (cs (Cookie) ) 检查”框和“引用 (cs (引用者) ) 检查框。

出现此问题后,请确定哪个客户端出现问题,以及该客户端的 IP 地址。 筛选该客户端的 IP 地址上的 IIS 日志,并查看 <cookie> 列。

注意 可以使用日志分析器来分析 IIS 日志。 若要下载 Log Parser,请访问以下 Microsoft 网站:

http://www.microsoft.com/download/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 获取来自该特定用户的请求列表后,搜索对登录页的请求。 你知道它们已重定向到此页面,并且希望在重定向发生之前查看请求。 如果看到类似于以下内容的内容,则客户端要么未发送 Cookie,要么在客户端和服务器之间的网络上删除了 Cookie。

这是初始登录名。

方法

网页

响应

饼干

获取

/Default.aspx

302 (重定向)

无 Cookie

获取

/Login.aspx

200 (成功)

无 Cookie

发布

/Login.aspx

302 (重定向)

无 Cookie

获取

/Default.aspx

200 (成功)

.ASPXAUTH

获取

/SomePage.aspx

302 (重定向)

不。ASPXAUTH Cookie

这些是其他请求,然后是对网站上没有 页面的请求。ASPXAUTH Cookie。

方法

网页

响应

饼干

获取

/SomePage.aspx

302 (重定向)

不。ASPXAUTH Cookie

获取

/Login.aspx

200 (成功)

不。ASPXAUTH Cookie

发布

/Login.aspx

302 (重定向)

不。ASPXAUTH Cookie

获取

/SomePage.aspx

200 (成功)

.ASPXAUTH


注意 除非正在创建持久性 Cookie,否则来自该用户的第一个请求不太可能具有表单身份验证 Cookie。 IIS 日志仅显示请求中收到的 Cookie。 在成功登录尝试后,对表单身份验证 Cookie 的第一个请求将在请求上发出。

情形 2


超过客户端的 Cookie 限制时,表单身份验证 Cookie 也可能丢失。 在 Microsoft Internet Explorer 中,限制为 20 个 Cookie。 在客户端上创建第 20 个 Cookie 后,以前的 Cookie 将从客户端的集合中删除。 如果 为 。将删除 ASPXAUTH Cookie,在处理下一个请求时,用户将被重定向到登录页。

可以采用相同方式排查这两种情况。 在重定向到登录页之前查看请求。 如果对此页的请求生成 Cookie,则需要进行调查。

可以使用 Fiddler 查看发送到客户端的 HTTP 标头。 捕获流量后,双击请求,然后单击“ 标头 ”以查看 Set-Cookie 标头。 如果跟踪成功的登录名,则会在成功登录的响应中看到 Set-Cookie 标头。

若要下载 Fiddler,请访问以下 Fiddler 网站:

http://www.fiddlertool.com/fiddler/

情形 3


请求离开客户端后,有各种层可能会影响正在发送的数据包。 若要确定网络设备是否正在删除 Cookie,必须在客户端和服务器上捕获网络跟踪,然后查看 Cookie 的请求正文。 你希望查看客户端请求以确保已发送 Cookie,并检查服务器跟踪,以确保服务器收到了 Cookie。

客户端请求

这是对用户进行身份验证后的 GET 请求。 表单身份验证票证信息以蓝色突出显示。 这确认 Cookie 信息已离开客户端。 使用网络捕获工具(如 Netmon)时,会看到实际通过适配器的流量。

47 45 54 20 68 74 74 70-3a 2f 2f 6c 6f 63 61 6c   GET http://local
68 6f 73 74 2f 46 6f 72-6d 73 41 75 74 68 4c 6f   host/FormsAuthLo
67 54 65 73 74 2f 57 65-62 46 6f 72 6d 31 2e 61   gTest/WebForm1.a
73 70 78 20 48 54 54 50-2f 31 2e 31 0d 0a 41 63   spx HTTP/1.1..Ac
63 65 70 74 3a 20 69 6d-61 67 65 2f 67 69 66 2c   cept: image/gif,
…Other headers of the GET request…
63 68 65 0d 0a 43 6f 6f-6b 69 65 3a 20 2e 41 53   che..Cookie: .AS
50 58 41 55 54 48 3d 33-43 45 46 39 42 39 41 30   PXAUTH=3CEF9B9A0
43 33 37 41 44 46 36 33-45 36 42 44 33 37 42 36   C37ADF63E6BD37B6
39 43 44 41 32 35 30 30-30 46 38 30 37 32 38 46   9CDA25000F80728F
35 31 43 39 35 36 36 44-31 34 43 35 34 31 34 35   51C9566D14C54145
38 31 43 39 33 45 32 41-30 31 44 44 43 44 45 46   81C93E2A01DDCDEF
32 34 41 31 37 34 32 39-34 31 30 43 30 39 37 34   24A17429410C0974
42 33 45 43 42 30 36 34-32 32 38 45 33 35 33 39   B3ECB064228E3539
39 41 38 32 32 42 33 42-39 33 36 44 46 30 38 46   9A822B3B936DF08F
42 41 42 44 33 45 31 30-32 44 30 30 32 31 30 43   BABD3E102D00210C
32 45 31 33 39 38 30 37-39 42 32 33 35 32 39 46   2E1398079B23529F
34 46 35 44 37 34 41 3b-20 50 72 6f 66 69 6c 65   4F5D74A; Profile
3d 56 69 73 69 74 6f 72-49 64 3d 62 32 34 65 62   =VisitorId=b24eb

服务器端请求

查看到达服务器的请求时,需要确保服务器收到的信息与客户端发送的信息相同。 如果服务器未收到相同的信息,则需要调查网络上的其他设备,以确定删除 Cookie 的位置。

注意 还存在删除 Cookie 的 ISAPI 筛选器实例。 如果确认 Web 服务器收到了 Cookie,但 IIS 日志中未列出该 Cookie,检查 ISAPI 筛选器。 可能需要删除筛选器才能查看问题是否已解决。

表单身份验证票证超时

重定向用户的另一个常见原因是表单身份验证票证已过期。 表单身份验证票证可以通过两种方式超时。 如果使用绝对过期,则会出现第一种情况。 对于绝对过期,身份验证票证将在到期时间过期时过期。 例如,将过期时间设置为 20 分钟,并且用户在下午 2:00 访问站点。 如果用户在下午 2:20 之后访问站点,则用户将被重定向到登录页。

如果使用滑动过期,则方案会稍微复杂一些。 如果用户在过期时间半后访问站点,则会更新 Cookie 和生成的票证。 例如,使用滑动过期设置 20 分钟的过期时间。 用户在下午 2:00 访问站点,并且用户会收到一个 Cookie,该 Cookie 设置为在下午 2:20 过期。 仅当用户在下午 2:10 之后访问站点时,才会更新过期时间。 如果用户在下午 2:09 访问站点,则票证不会更新,因为一半的过期时间尚未过去。 如果用户随后等待 12 分钟,在下午 2:21 访问站点,则票证将过期。 用户被重定向到登录页。

解决此类问题的一种方法是记录表单身份验证 Cookie 和票证信息。 这样,就可以查看 IIS 是否收到了 Cookie 以及值。 为此,可以编写 HttpModule,然后将该模块插入请求管道。 无需修改应用程序代码即可获取所需的信息。

附加示例在 Microsoft .NET Framework 1.1 和 .NET Framework 2.0 中有效,并始终提供注释。 此示例包含以下文件:

  • FormsAuthEvents.cs:实现 IHttpModule 并关联到 Application_BeginRequest 事件的类。

  • FormsAuthInfo.cs:检索 Cookie 并解密 forms 身份验证票证的类。 它还会检查应用程序的 Web.config 文件,以确保已启用表单身份验证。

  • FormsAuthConfig.cs:从 FormsAuthLogger.config 文件中读取信息的类。

  • Log.cs:接受 stringbuilder 并将值写入日志文件的文件。

  • FormsAuthLogger.config:Log.cs 文件读取的 XML 文件。 此文件必须位于具有生成 DLL 的 /bin 文件夹中。 该文件允许你配置以下各项:

    • 按 IP 筛选:可以按客户端 IP 筛选数据的捕获。 这样,可以仅记录来自已知重现问题的客户端的请求。 这会减小日志的大小。

    • 捕获类型:指定保存文件的位置。 默认值为“临时 ASP.NET 文件”文件夹,但只要工作进程帐户能够写入文件夹,就可以将其保存在任何位置。

注意 我将提供 FormsAuthLogger.zip 文件中提供的代码的下载链接。

我将在此处指出main区域:

  1. 创建实现 IHttpModule 接口的类。

    public class FormsAuthEvents : IHttpModule 
    {
    …code…
    }
  2. 连接要查看的事件。 在此示例中,我们将使用 Application_BeginRequest 事件。 这样,我们可以调查每个请求,并确定它是否具有 Forms 身份验证 Cookie,并在 Cookie 存在时记录 FormsAuthenticationTicket。

    public void Init(HttpApplication application) 
    {
    //Wire up the BeginRequest event
    application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
    }
  3. 实现 Application_BeginRequest 事件。

    private void Application_BeginRequest(Object source, EventArgs e)
    {
       …code to log the ticket…
    }
    
  4. 检索表单身份验证 Cookie,然后将其解密。

  5. 记录值。 除了表单信息之外,我建议记录以下内容。 如有必要,这有助于将表单身份验证信息排到 IIS 日志:

    • 日期:允许查看请求的传入时间。

    • RequestType:显示请求是 Get 还是 Post。

    • URL:显示导致问题的请求模式。

    • 引荐

    • ClientIP:将请求中的关联到特定客户端。

需要更多帮助?

需要更多选项?

了解订阅权益、浏览培训课程、了解如何保护设备等。

社区可帮助你提出和回答问题、提供反馈,并听取经验丰富专家的意见。

此信息是否有帮助?

你对语言质量的满意程度如何?
哪些因素影响了你的体验?
按“提交”即表示你的反馈将用于改进 Microsoft 产品和服务。 你的 IT 管理员将能够收集此数据。 隐私声明。

谢谢您的反馈!

×