0

设置

我正在使用自定义表单身份验证 - 所有标准的东西。

在我的帐户控制器上的登录操作中,

  • 我根据数据库检查用户的详细信息
  • 如果成功,我将创建表单身份验证票
  • 将登录的成员数据库行 ID 存储在工单的 UserData 中
  • 加密票证
  • 将票存储在 cookie 中
  • 将 cookie 添加到 Reponse.Cookies 集合
  • 重定向到主控制器上的索引操作

我在全局 asax 中为 AuthenticateRequest 事件注册了一个处理程序。在我的处理程序中,

  • 我从 HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
  • 如果 cookie 存在,我将解密 cookie 中 Forms Authentication 票证的值
  • 使用存储在身份验证票证 UserData 中的 Id 从数据库中检索用户的详细信息。
  • 创建一个自定义主体并将用户(它具有自定义 LoggedInUser 属性)设置为我从数据库中检索到的用户。
  • 将 HttpContext.Current.User 设置为自定义主体

问题

我在登录后调试主页请求,并注意到 global.asax 中的 AuthenticateRequest 处理程序在每个页面请求中被多次命中。我检查了 HttpContext.Current.Request.Path,这是因为我页面上的每个资源(实际上是每个 HTTP GET)都在触发身份验证请求,所以,GET jquery.js、GET logo.png 等......

问题

在第一个处理的 AuthenticateRequest 中,我转到数据库,然后将 HttpContext.Current.User 设置为我的自定义主体。什么是避免进入数据库以获取导致 AuthenticatRequest 触发的后续 HTTP GET 的好方法。实际上,只进行一次身份验证,直到用户关闭浏览器或身份验证票证到期。

TIA

4

1 回答 1

1

我建议您编写一个全局操作过滤器,而不是使用AuthenticateRequestGlobal.asax 中的方法。这样,操作过滤器将仅在执行某些操作并填充用户之前应用。事实上,自定义[Authorize]属性是实现这一目标的最佳方式:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        // TODO: go ahead and work with the UserData from the authentication cookie
        // basically all the steps you described for your AuthenticateRequest handler
        // except for checking the presence of the forms authentication cookie because
        // we know that at this stage it exists and the user was successfully authorized

        return true;
    }
}
于 2012-06-12T16:03:25.510 回答