var ID = new GenericIDentity(Request.headers["ceID"]); var rp = new MyRoleProvIDer(); var principal = new GenericPrincipal(ID,rp.GetRolesForUser(ID.name)); Context.User = principal;
问题是我们需要使用Web服务来获取角色,并且因为每次每个用户访问页面时都会进行该调用,所以Web服务被击中的次数太多了.
理想的解决方案是,如果我们可以将角色存储在会话变量中,则会话在Application_AuthenticateRequest中不可用.我们考虑在应用程序变量中存储一个包含所有用户条目的字典,但我希望我们能找到更好的解决方案.
有没有什么办法可以存储当前用户的角色,以便它们可以在Application_AuthenticationRequest中使用?我们很有安全意识; cookie是一个有效的选择吗?
解决方法 我将创建一个静态类来保存所有当前用户的角色列表(基本上扩展到您的词典概念):如果列表中不存在给定ID的角色,我们将从Web服务中检索它们.否则我们返回存储的角色.我们需要在一定数量的用户不活动之后使数据到期的方法(我们不希望所有用户都在内存中保留所有角色),因此我们将实现自己的过期机制(在我的示例中为20分钟).
这是我写这个课的方式,以及我将如何使用它:
/// <summary> /// This is the static class that will hold the roles for all active users (active users /// are those that have been using the website within the last 20 minutes). /// </summary> public static class MyRoles { /// <summary> /// This class holds your roles /// </summary> private class Principal { private DateTime lastAccess; // Our expiration timer private System.Security.Principal.GenericPrincipal principal; // Our roles public Principal(System.Security.Principal.GenericPrincipal principal) { this.principal = principal; this.lastAccess = DateTime.Now; } public System.Security.Principal.GenericPrincipal GenericPrincipal { get { // We reset our timer. It will expire 20 minutes from Now. this.lastAccess = DateTime.Now; return principal; } } /// <summary> /// This tells us if a user has been active in the last 20 minutes /// </summary> public bool IsValID { get { // ValID within 20 minutes from last call return DateTime.Now <= this.lastAccess.AddMinutes(20); } } } /// <summary> /// This will hold IDs and related roles /// </summary> private static Dictionary<string,Principal> IDs = new Dictionary<string,Principal>(); /// <summary> /// Method to retrIEve roles for a given ID /// </summary> /// <param name="header">Our ID</param> /// <returns></returns> public static System.Security.Principal.GenericPrincipal GetRoles(string header) { if (IDs.ContainsKey(header) && IDs[header].IsValID) { // We have roles for this ID return IDs[header].GenericPrincipal; } else { // We don't have this ID (or it's expired) so get it from the web service var ID = new System.Security.Principal.GenericIDentity(header); var principal = new System.Security.Principal.GenericPrincipal(ID,new MyRoleProvIDer().GetRolesForUser(ID.name)); // Store roles IDs.Add(header,new Principal(principal)); return principal; } } } protected voID Application_AuthenticateRequest(object sender,EventArgs e) { // This is how we use our class var principal = MyRoles.GetRoles(Request.headers["ceID"]); }
请注意,我的示例代码没有考虑存储GenericPrincipal实例列表所需的内存占用量.我的目标只是让您了解如何在不使用Session对象的情况下持久化(和过期)用户数据.
20分钟到期机制可以轻松链接到Session_End事件,以便在会话结束后(如果您正在使用InProc会话)它将使数据到期.
另请注意,与会话一样,此解决方案仅适用于单服务器环境.如果您具有负载平衡环境(2个或更多Web服务器),则必须将数据保留到数据库.
我希望这能够帮到你.如果没有,请告诉我原因,我会尽力帮助你:)
总结以上是内存溢出为你收集整理的c# – 如何持久保存Application_AuthenticateRequest中所需的会话特定值?全部内容,希望文章能够帮你解决c# – 如何持久保存Application_AuthenticateRequest中所需的会话特定值?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)