我的应用中的静态公共变量是否会与同一个应用中的其他用户共享?

时间:2010-11-11 19:47:38

标签: c# .net asp.net static class-design

由于我不想讨论的原因,我需要为我的应用程序创建一个自定义身份验证系统。我只是在审查系统,如果我的解决方案是线程安全的,我有一些疑问。我的目标是创建一个解决方案,允许我的应用程序对用户进行一次身份验证,并且用户身份验证信息将由所使用的所有母版页,页面,类,用户控件等共享。 (但不能在用户之间共享相同的信息)

这是我的设置:

PageHttpModule.cs - 它作为httpModule添加到web.config。

public class PageHttpModule : IHttpModule
{
    public void Init(HttpApplication app)
    {
        app.AuthenticateRequest += new EventHandler(OnAuthenticateRequest);
    }

    public void OnAuthenticateRequest(Object s, EventArgs e)
    {
         CurrentUser.Initialize();
    }

    public void Dispose() { }
}

CurrentUser.cs

public static class CurrentUser
{
  public static bool IsAuthenticated { get; private set; }
  public static string Email {get; set;}
  public static string RealName {get; set;
  public static string UserId {get; set;}

    public static void Initialize()
    {
        CurrentUser.AuthenticateUser();
    }


    Note: this is a scaled down version of my authentication code.

    public static void AuthenticateUser()
    {
        UserAuthentication user = new UserAuthentication();
        user.AuthenticateUser();

        if (user.IsAuthenticated)
        {
            CurrentUser.IsAuthenticated = true;
            CurrentUser.UserId = user.UserId;
            CurrentUser.Email = user.Email;
            CurrentUser.RealName = user.RealName;
        }
     }
}

UserAuthentication.cs

public class UserAuthentication
{

    public string Email { get; set; }
    public string RealName { get; set; }
    public string UserId { get; set; }
    public bool IsAuthenticated { get; private set; }

    public UserAuthentication()
    {
        IsAuthenticated = false;
        Email = String.Empty;
        RealName = String.Empty;
        UserId = String.Empty;
    }

    public void AuthenticateUser()
    {

        //do some logic here.. if the user is ok then 
        IsAuthenticated = true
        Email = address from db
        UserId = userid from db;
        Realname = name from db;
   }
}

我已经在3种不同的浏览器之间进行了测试,它似乎运行良好,但我仍然在学习,并且不想犯错误。

如果我的逻辑是完全错误的,那么我应该怎么做呢?所以我不必直接在每个页面上进行用户查找?

4 个答案:

答案 0 :(得分:3)

不,这不是线程安全的。对于生活在单独进程或AppDomains中的应用程序的实例,这将很好。但是如果你的ASP.NET服务器要使用线程一次服务多个请求,那么如果两个人同时尝试使用该应用程序,你将会产生一些非常糟糕的副作用。

答案 1 :(得分:1)

为什么不按照微软推荐的方式去做呢?

http://msdn.microsoft.com/en-us/library/9wff0kyh.aspx

我已经通过这种方式完成了自定义身份验证,并且运行正常。


这是另一个应该证明有用的链接:

http://blogs.msdn.com/b/ncl/archive/2009/05/05/custom-http-authentication-schemes.aspx

答案 2 :(得分:1)

Init方法中,HttpApplication参数描述为:

  

一个HttpApplication,提供对ASP.NET应用程序中所有应用程序对象通用的方法,属性和事件的访问

这里的关键是应用程序的生命周期中有一个PageHttpModule,应用程序生命周期中存在的所有静态对象都将共享这些变量。

但是...... CurrentUser的生命周期仅在OnAuthenticateRequest事件的范围内,除非某些其他引用使对象保持活动状态。如果它是PageHttpModule成员级变量,那么您会遇到一些您会立即注意到的问题。但是,在您的情况下,只要您没有多次同时处理OnAuthenticateRequest电话,您就可以正常工作

你的问题的答案是否定的,你不能保证是线程安全的。如果两个身份验证请求同时进入,则无法保证在另一个事件开始之前完成一个事件,在这种情况下,当第二个用户确实是第一个登录的用户时,第二个用户可以显示身份验证。


更新
我认为问题的一部分来自于对AuthenticateRequest的误解......当调用此事件时,用户已经通过Windows或Forms身份验证进行了身份验证...您刚收到通知它发生了。实际上,属性User.Identity.IsAuthenticated已经设置(我相信即使用户验证失败,此事件也会触发,但我不会在没有仔细检查的情况下发誓)。

如果我了解您的目标,那么您真的想要编写自己的自定义成员资格提供程序。如果采用这种方法,您将获得内置身份验证的所有好处......所有与身份验证相关的标准属性都将被设置和访问,并将以您希望的方式与用户的会话隔离。 / p>

编写自定义提供程序不是一件小事,但它是可行的,您应该能够重用当前用于类的许多逻辑和代码。

尝试完全重写认证机制将会遇到痛苦,复杂的箍。

一些链接:
http://www.devx.com/asp/Article/29256/0/page/3
http://www.codeproject.com/KB/aspnet/WSSecurityProvider.aspx
http://msdn.microsoft.com/en-us/library/f1kyba5e%28v=VS.90%29.aspx

您必须实现的属性可能看起来令人生畏,但除非您需要特定功能(例如ResetPassword),否则您只需抛出NotImplementedException。仅编码您将使用的内容。

答案 3 :(得分:0)

你用IHttpModule做的事情似乎是解决这类问题的好方法。 microsoft所述的http模块的目的之一是启用任何类型的特殊身份验证。当http模块初始化时,它对新请求使用相同的实例。由于你没有任何全局变量,我不太确定如何解决你的线程安全问题。看起来你正在阅读一些数据,所以请详细说明!