【问题标题】:ASP.NET MVC - Authenticate once and only once until session outASP.NET MVC - 验证一次且仅一次,直到会话结束
【发布时间】:2012-06-12 16:00:51
【问题描述】:

设置

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

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

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

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

  • 我从 HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName] 检索 cookie;
  • 如果 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

【问题讨论】:

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


    【解决方案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;
        }
    }
    

    【讨论】:

    • 这是一个很好的解决方案,只要用户不需要对单个资源(例如照片、pdf 或用户可能想要控制访问的其他文件)提供授权。跨度>
    • 这些资源通常应该通过控制器操作提供服务,因此回退到标准的 ASP.NET MVC 授权过程。
    • 不一定,例如,可能会使用 web.config 位置。但是,由于身份验证是在操作级别完成的,因此在全局级别不会有任何授权。这可能没问题。我只想指出,这种方法仅在您仅保护控制器操作时才有效。
    • 就我个人而言,我从不在我的 ASP.NET MBVC 应用程序中使用 <location> 元素来执行身份验证和授权。
    • 这是一种执行身份验证和授权的有趣方式。我从来没有考虑过这个,但现在正在研究。我会自动走下 Global.Authenticate_Request 路线。我发现这篇文章 (blogs.msdn.com/b/rickandy/archive/2011/05/02/…) 非常有用。 Darin,我将根据您的建议和测试更新我的解决方案,然后发布更多 cmets。谢谢你的建议……学习新东西总是好的。
    猜你喜欢
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多