我可以从不同于发出请求的会话中放弃InProc ASP.NET会话吗?

时间:2008-11-03 03:06:43

标签: asp.net session-state single-sign-on

我们有一个使用集中身份验证服务器(CAS)进行单点登录的应用程序。我们想进行单点注销,这样如果用户退出一个应用程序(比如一个前端门户),用户将使用相同的单点登录票据自动退出所有应用程序。

期望每个应用程序在登录该应用程序时都会向CAS注册一个签名挂钩(URL)。当CAS收到其中一个应用程序的注销请求时,它会为共享SSO票证的所有应用程序调用注销挂钩。

我的问题是:有没有办法放弃来自不同会话的InProc会话?我认为,由于HTTP请求将来自CAS服务器,它将获得自己的会话,但它是我想要终止的用户的会话。我非常清楚如何使用单独的会话状态服务器执行此操作,但我想知道是否可以使用InProc会话状态。

4 个答案:

答案 0 :(得分:3)

哈哈,嗯......看起来你可以。我想知道自己是否有任何办法可以做到这一点,结果是,有。

使用InProc时,InProcSessionStateStore(内部类)会在内部(非公共)缓存中保持会话状态。您可以通过反射访问此缓存并手动删除会话状态。

using System;
using System.Reflection;
using System.Web;

object obj = typeof(HttpRuntime).GetProperty("CacheInternal", 
    BindingFlags.NonPublic | BindingFlags.Static)
        .GetValue(null, null);

if (obj != null)
{
    MethodInfo remove = obj.GetType()
        .GetMethod("Remove", BindingFlags.NonPublic | BindingFlags.Instance, 
            Type.DefaultBinder, new Type[] { typeof(string) }, null);

    object proc = remove.Invoke(obj, new object[] { "j" + state.SessionID });
}

最终结果是,下一个请求将采用相同的SessionID,但HttpSessionState将为空。你仍然会得到Session_Start和Session_End事件。

答案 1 :(得分:2)

在做了一些挖掘并考虑到目前为止提供的答案后,我想出了一个替代方案,让我继续使用InProc会话。基本上,它包括扩展已经处理单点登录的HttpModule到检测到的CAS签名,并将浏览器重定向到应用程序注销页面。

概要

点登录:

  1. 对于每个新的单点登录请求,创建一个新的SSO cookie并在其中编码唯一值以标识会话(而不是会话ID,因此不会泄露)。
  2. 构造使用标识符编码的注销回调网址,并将其注册到CAS服务器。
  3. 签出:

    1. 当从CAS服务器收到注销请求时,解码标识符并将其存储在应用程序范围的缓存中。这需要固定在缓存中至少足够长,以使会话自然过期。
    2. 对于每个请求,查找SSO cookie并根据缓存的已注销会话标识符检查其值。如果有匹配,请删除SSO cookie并将浏览器重定向到应用程序的注销URL。
    3. 对于每次退出,请检查是否有SSO Cookie,如果有,请将退出请求转发给CAS。无论如何,放弃用户的会话,并将其签署出应用程序。
    4. 的Page_Load:

      1. 检查是否存在SSO cookie。如果没有,请重定向到退出页面。

答案 2 :(得分:1)

答案 3 :(得分:1)

使用InProc SessionState,您将无法访问数据...使用StateServer,您仍然会遇到尝试访问正确API以删除会话的粘性方案。

您很可能希望使用数据库支持的状态解决方案,如预先打包的SqlServer状态提供程序或第三方解决方案,如DOTSS:http://codeplex.com/dotss

使用数据库支持的解决方案,您将能够按会话ID在表中查找状态记录并将其标记为已完成。这些技术将根据您选择的提供商而有所不同。