FormsAuthentication.RedirectFromLoginPage - 非常奇怪且不一致的结果

时间:2009-10-08 18:18:54

标签: asp.net webforms forms-authentication


我正在试图弄清楚 FormsAuthentication.RedirectFromLoginPage (在方法 M()中调用),执行重定向方法 M 完成其执行,或者页面是否首先完成其生命周期,然后才重定向。但由于行为不一致,我无法弄明白:


protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        FormsAuthentication.RedirectFromLoginPage("someUser", false);
    }


protected void LogOut_Click(object sender, EventArgs e)
{
    FormsAuthentication.SignOut();
    Session["LogOut"] = "LogOut_Click event handler";
}

protected void ClickMe_Click(object sender, EventArgs e)
{
    Session["ClickMe"] = "ClickMe_click event handler";
}


如果在回发用户点击 LogOut 按钮,则会在重定向页面之前执行 LogOut_Click()。但如果在回发用户点击 ClickMe 按钮,则会在调用 ClickMe_Click 事件处理程序之前重定向该页面。

为什么?因此,基于什么标准, FormsAuthentication.RedirectFromLoginPage 决定在重定向之前应该执行哪些事件处理程序?


感谢名单


编辑:


  

FormsAuthentication.RedirectFromLoginPage()方法与注销无关。它用于手动记录某人并将其重定向到他们最初尝试访问的页面。

我并不暗示它与退出有关


  

但是,查看代码示例,您可能会问为什么代码会继续在LogOut_Click函数中执行,即使用户已注销。

不,我也没有问过。


  

现在,我也想到你可能会询问FormsAuthentication.RedirectToLoginPage而不是RedirectFromLoginPage。

我没有问过这个


我问的是为什么在Page_Load中调用FormsAuthentication.RedirectFromLoginPage时,如果回发是由LogOut按钮引起的,那么LogOut_Click()方法会在重定向页面之前运行,但如果ClickMe按钮导致回发,则单击Me_Click()事件处理程序在页面重定向之前没有机会运行。换句话说,我希望ClickMe_Click在页面重定向之前也有机会运行(假设ClickMe按钮导致回发)

2 个答案:

答案 0 :(得分:4)

好,

从我尝试这个场景中可以看出来的是这个。

重定向不会阻止页面完成生命周期。

Microsoft应该为RedirectFromLoginPage添加另一个重载,包括'endResponse',就像它为Response.Redirect做的那样。不幸的是他们没有。由于Page_Load在任何回发事件之前运行,并且您在事件触发之前调用RedirecFromLoginPage,因此您需要停止当前页面完成当前处理生命周期。

它远非优雅,但却放了

FormsAuthentication.RedirecFromLoginPage("someUser", false);    
Response.End();

在您的RedirectFromLoginPage停止当前页面生命周期并因此停止任何其他事件触发后,您应该获得您正在寻找的操作。至少我希望。然而,这将导致'System.Threading.ThreadAbortException',就像你将true.Indirect参数传递给Response.Redirect一样。

希望这有帮助。

答案 1 :(得分:1)

编辑 - 新答案

行。我看到我完全错误地读了这个问题。遗憾。

我发布了这个新答案,但我担心我仍然不会为你回答“为什么”。我知道这一点。

根据Response.Redirect方法的备注部分文档,它说

  

重定向呼叫结束提升a   ThreadAbortException异常   完成。

但是,在FormsAuthentication.RedirectFromLoginPage()的文档中没有类似的注释。知道没有文档是完美的,但是Microsoft在MSDN库方面表现非常出色,所以我只能假设它的原因是他们选择不出于某种原因在FormsAuthentication.RedirectFromLoginPage()方法中调用End。也许是疏忽?

无论如何,对我而言,这似乎是一个错误。您认为两种方法的行为都相同,因为两种方法都是重定向方法,当然,这不是您问题的答案。我想现在我和你还在同一条船上,想知道为什么会这样。

我确定你已经想到了这一点,但我相信你可以通过使用正常的Response.Redirect方法而不使用FormsAuthentication.RedirectToLoginPage来解决这个问题。老实说,我以前从未见过使用过的RedirectToLoginPage,所以我很好奇为什么要使用它而不是Response.Redirect。

结束编辑 - 原始答案

我不确定我是否正确阅读此内容。

FormsAuthentication.RedirectFromLoginPage()方法与记录 out 无关。它用于手动记录某人 并将其重定向到他们最初尝试访问的页面。

但是,查看代码示例,您可能会问为什么代码会继续在LogOut_Click函数中执行,即使用户已注销。这很简单。当Application_AuthenticateRequest事件触发时,将检查安全权限,该事件在事件处理代码之前。

因此,即使您已将用户注销,也会在检查凭据时对用户进行身份验证。只要用户在该页面中,运行时就不会再次检查凭证。

我试图想一个现实世界的比较并提出这个问题。在我们公司,我们有一张刷卡,我们必须用它来进入建筑物和某些敏感区域。如果我在当天早些时候受雇,并在当天晚些时候被解雇,我仍然在大楼里。我可以清理我的桌子等等。所以只要我还没有离开它,我仍然可以在建筑物内做事。

这也适用于您的代码......用户已经过身份验证并且在页面执行生命周期中,因此允许代码继续。

这是否应该以这种方式进行辩论。 Microsoft可以对其进行编码,以便调用FormsAuthentication.SignOut()也可以选择性地终止类似于Response.Redirect的处理,但显然基于您没有的代码示例。相反,调用SignOut()只会删除身份验证cookie。

http://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.signout.aspx

现在,我也想到您可能会询问FormsAuthentication.RedirectToLoginPage而不是RedirectFromLoginPage。但是,您不在代码或问题的任何其他部分中显示RedirectToLoginPage。如果您想要将人员记录下来并立即重定向到腰部页面,您需要调用FormsAuthentication.SignOut(),然后调用FormsAuthentication.RedirectToLoginPage(),如上面发布的链接所示。