ASP.NET MVC - 只进行一次身份验证,直到会话结束

时间:2012-06-12 16:00:52

标签: asp.net-mvc-3 authentication request

设置

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

在我的帐户控制器的“登录”操作中

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

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

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

问题

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

问题

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

TIA

1 个答案:

答案 0 :(得分:1)

我建议您编写全局操作过滤器,而不是在Global.asax中使用AuthenticateRequest方法。这样,动作过滤器将仅在执行某些操作并填充用户之前应用。事实上,自定义[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;
    }
}