在http处理程序中验证

时间:2015-11-30 14:22:46

标签: asp.net httphandler

我正在为域中的所有应用执行SSO

到目前为止,我所做的事情是

  1. 使用表单身份验证创建了一个父网站,其中执行了登录
  2. 将所有子应用程序的身份验证模式删除为无
  3. 在所有子应用中添加了一个处理程序,用于检查用户是否已通过身份验证并获取应用的用户详细信息
  4. 处理程序代码如下

    public class MyHandler : IHttpHandler, IRequiresSessionState  
    {
        public bool IsReusable
        {
            get { return true; }
        }
    
        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.IsAuthenticated)
            {
                if (context.Session["UserDetails"] == null)
                {
                    string userName = HttpContext.Current.User.Identity.Name;
                    UserManagement userMngmt = new UserManagement();
                    userMngmt.GetLoggedUserDetails(userName);
                   // context.Response.Redirect(context.Request.Url.ToString(), true);
                }
            }
            else
            {
                context.Response.Redirect("/SSO");
            }
        }
    }
    

    这个想法是,如果他通过身份验证获取用户名并获取他的详细信息并存储在会话中并继续加载带有用户详细信息的请求页面。

    但是现在页面没有加载。我知道在检查后我必须加载所请求的页面。如何这样做。

1 个答案:

答案 0 :(得分:2)

我认为你在错误的地方挂钩。 IHttpHandler是单个网址或特定网址集的处理程序。逻辑应该转到IHttpModule(结帐https://msdn.microsoft.com/en-us/library/ms227673(v=vs.100).aspx)。或Global.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)
{
   var context = ((HttpApplication)sender).Context;
   if (!context.Request.IsAuthenticated &&     
       !context.Request.Url.PathAndQuery.StartsWith("/SSO", 
         StringComparison.OrdinalIgnoreCase))
   {
     context.Response.Redirect("/SSO");
   }

}

因此,您可以将任意代码注入每个请求(在您的情况下,某些会话预热)并且您不必在任何地方重定向 - 因为页面将在执行您的代码后加载。

另请注意,依靠某些"魔法"这一事实并不是一个好主意。将填写一些缓存;更好的方法是使用延迟加载。

public UserData GetUserData(HttpContext context)
{
    if (!context.Request.IsAuthenticated)
    {
      throw new Exception("Unauthorized");
    }

    var result = context.Session["UserDetails"];
    if (result == null)
    {
      string userName = HttpContext.Current.User.Identity.Name;
      var userMngmt = new UserManagement();
      result = userMngmt.GetLoggedUserDetails(userName);
      context.Session["UserDetails"] = result;
    }
    return result;
}

因此,您仍然可以使用Session作为缓存,但是只有在明确请求时才将其用作缓存,并且您的数据来自哪个更清晰(您不必通过整个应用程序来查找Session["UserDetails"]的设置位置

同时查看ASP.NET MVC 4 intercept all incoming requests(其中的MVC,但模块概念/全局应用程序概念在ASP.NET和MVC之间没有变化)