我正在为域中的所有应用执行SSO
到目前为止,我所做的事情是
处理程序代码如下
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");
}
}
}
这个想法是,如果他通过身份验证获取用户名并获取他的详细信息并存储在会话中并继续加载带有用户详细信息的请求页面。
但是现在页面没有加载。我知道在检查后我必须加载所请求的页面。如何这样做。
答案 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之间没有变化)