3

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

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

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

4

4 回答 4

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 事件。

于 2009-05-19T13:17:39.297 回答
2

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

大纲:

登录:

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

登出:

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

页面加载:

  1. 检查是否存在 SSO cookie。如果没有,请重定向到退出页面。
于 2008-11-03T04:10:24.650 回答
1

没办法。

http://forums.asp.net/p/416094/416094.aspx#416094

于 2008-11-03T03:18:38.840 回答
1

使用 InProc SessionState,您将无法访问数据……使用 StateServer,您仍然会有一个棘手的场景,试图访问正确的 API 以删除会话。

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

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

于 2008-11-03T03:24:44.100 回答