这种ASP.NET会话访问技术是否是多用户安全的?

时间:2010-03-09 23:31:26

标签: .net asp.net session thread-safety

我正在研究一个设计模式,该模式出现在我公司的很多项目中。它在历史上运行正常,但是我听到其他一些开发人员认为使用这种模式可能会导致会话损坏。我正在寻找Stack Overflow上其他.NET开发人员的见解。

基本上,有一个类 - 通常是static或Singleton模式,主要取决于编写它的开发人员 - 存储在App_Code中。

此类封装了通过属性对当前会话的访问。所有这些属性都采用以下形式:

public static class SessionHelper
{
    public static string SessionValue
    {
        get
        {
            object o = HttpContext.Current.Session["sessionValueName"];
            if (o == null)
            {
                // Replace the following with code to store & retrieve
                // a default value of the appropriate datatype.
                o = string.Empty;
                HttpContext.Current.Session["sessionValueName"] = o;
            }

            return o.ToString(); // or cast, ensure cast is valid & return.
        }
        set
        {
            HttpContext.Current.Session["sessionValueName"] = value;
        }
    }

    // Other properties, strongly-typed, as above.
}

(当类是Singleton时,这些不是静态的。)

过去我在网站上看到过静态数据的问题,很大程度上是因为静态数据用于维护每个会话状态。 (例如,我看到了静态声明的“每用户”代码隐藏成员。不是我的代码;我的团队是编写这个烂摊子的公司的清理工作人员。)

但是,因为这只是HttpContext.Current.Session的静态条目,所以它似乎应该是安全的,因为它与Page类在Session中封装它的基本没有任何区别。属性。正如我所说的那样,我的公司所使用的其他网站都没有使用过这种模式,因此它遇到了任何问题 - 其中包括一些非常庞大且高度活跃的用户群。但我想获得一个全新的视角。

是否存在潜在的多用户问题,竞争条件或其他可能导致上述模式中的会话损坏的失败/缺陷?

2 个答案:

答案 0 :(得分:3)

我使用的方法与你提出的方法非常相似,到目前为止还没有发现任何问题。

可能有一件事需要关注的是硬编码的会话密钥:您永远无法确定相同的密钥在其他位置不会用于其他目的。

这就是为什么我只依赖一个密钥,用于在ASP.NET会话中存储“我的会话”。然后,所有会话数据都将作为“my session”对象的常规属性实现。


以下是我的方法:

public class MySession
{
    // private constructor
    private MySession() {}

    // Gets the current session.
    public static MySession Current
    {
      get
      {
        MySession session =
          (MySession)HttpContext.Current.Session["__MySession__"];
        if (session == null)
        {
          session = new MySession();
          HttpContext.Current.Session["__MySession__"] = session;
        }
        return session;
      }
    }

    // **** add your session properties here, e.g like this:
    public string Property1 { get; set; }
    public DateTime MyDate { get; set; }
    public int LoginId { get; set; }
}

此类在ASP.NET会话中存储自身的一个实例,并允许您以类型安全的方式从任何类访问会话属性,例如:

int loginId = MySession.Current.LoginId;

string property1 = MySession.Current.Property1;
MySession.Current.Property1 = newValue;

DateTime myDate = MySession.Current.MyDate;
MySession.Current.MyDate = DateTime.Now;

这种方法有几个优点:

  • 它可以帮助您避免大量的类型转换
  • 您不必在整个应用程序中使用硬编码会话密钥(例如Session [“loginId”]
  • 您可以通过在MySession
  • 的属性上添加XML文档注释来记录您的会话项目

答案 1 :(得分:2)

这是安全的。您通过某些静态属性或静态类访问它的事实完全无关紧要。这是一种语言抽象。 Session提供程序负责将请求映射到正确的会话...所以除非有错误,否则你就是A-OK。