我可以从不同于发出请求的会话中放弃InProc ASP.NET会话吗?
-
06-07-2019 - |
题
我们有一个使用集中身份验证服务器(CAS)进行单点登录的应用程序。我们想进行单点注销,这样如果用户退出一个应用程序(比如一个前端门户),用户将使用相同的单点登录票据自动退出所有应用程序。
期望每个应用程序在登录该应用程序时都会向CAS注册一个签名挂钩(URL)。当CAS收到其中一个应用程序的注销请求时,它会为共享SSO票证的所有应用程序调用注销挂钩。
我的问题是:有没有办法放弃来自不同会话的InProc会话?我认为,由于HTTP请求将来自CAS服务器,它将获得自己的会话,但它是我想要终止的用户的会话。我非常清楚如何使用单独的会话状态服务器执行此操作,但我想知道是否可以使用InProc会话状态。
解决方案 2
在做了一些挖掘并考虑到目前为止提供的答案后,我想出了一个替代方案,让我继续使用InProc会话。基本上,它包括扩展已经处理单点登录的HttpModule到检测到的CAS签名,并将浏览器重定向到应用程序注销页面。
概要
点登录:
- 对于每个新的单点登录请求,创建一个新的SSO cookie并在其中编码唯一值以标识会话(而不是会话ID,因此不会泄露)。
- 构造使用标识符编码的注销回调网址,并将其注册到CAS服务器。 醇>
- 当从CAS服务器收到注销请求时,解码标识符并将其存储在应用程序范围的缓存中。这需要固定在缓存中至少足够长,以使会话自然过期。
- 对于每个请求,查找SSO cookie并根据缓存的已注销会话标识符检查其值。如果有匹配,请删除SSO cookie并将浏览器重定向到应用程序的注销URL。
- 对于每次退出,请检查是否有SSO Cookie,如果有,请将退出请求转发给CAS。无论如何,放弃用户的会话,并将其签署出应用程序。 醇>
- 检查是否存在SSO cookie。如果没有,请重定向到退出页面。 醇>
签出:
的Page_Load:
其他提示
使用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事件。
使用InProc SessionState,您将无法访问数据...使用StateServer,您仍然会遇到尝试访问正确API以删除会话的粘性方案。
您很可能希望使用数据库支持的状态解决方案,如预先打包的SqlServer状态提供程序或第三方解决方案,如DOTSS: http://codeplex.com/dotss
使用数据库支持的解决方案,您将能够按会话ID在表中查找状态记录并将其标记为已完成。这些技术将根据您选择的提供商而有所不同。