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

发布于 2024-10-01 11:28:50 字数 2175 浏览 9 评论 0原文

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

这是我的设置:

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 个不同的浏览器之间进行了测试,它似乎工作正常,但我仍在学习,不想犯一个巨大的错误。

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

For reasons I would rather not discuss, I need to create a custom authentication system for my app. I was just reviewing the system and am having some doubts if my solution is thread safe. My goal was to create a solution that would allow my app to authenticate a user one time and that users authentication info would be shared by all master pages, pages, classes, user controls, etc that are used. (But not share the same info between users)

Here is my setup:

PageHttpModule.cs - this is added to the web.config as a httpModule.

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;
   }
}

I have tested between 3 different browsers and it seems to work fine, but I am still learning and don't want to make a huge mistake.

If my logic is totally wrong, then how should I do it so I dont have to put user lookups on every page directly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

伪心 2024-10-08 11:28:50

不,这不是线程安全的。对于位于单独进程或 AppDomain 中的应用程序实例,这就很好了。但是,如果您的 ASP.NET 服务器要使用线程同时处理多个请求,并且两个人尝试同时使用该应用程序,则会产生一些非常严重的副作用。

No, this is not thread-safe. For instances of the application living in separate processes or AppDomains, this will be just fine. But if your ASP.NET server is going to serve multiple requests at once using threading, you are going to have some very bad side effects if two people try to use the application at the same time.

雪若未夕 2024-10-08 11:28:50

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

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

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

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

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

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

如果我理解您的需求,那么您实际上是在尝试编写自己的自定义会员资格提供程序。如果您采用这种方法,您将获得内置身份验证的所有好处...与身份验证相关的所有标准属性都将被设置和访问,并将以您想要的方式隔离到用户会话。

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

尝试完全重写身份验证机制将是跳过痛苦、复杂的循环。

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

您必须实现的属性可能看起来令人畏惧,但除非您需要特定功能(例如 ResetPassword),否则您可以简单地抛出一个 NotImplementedException。只编写您将使用的代码。

In the Init method, the HttpApplication parameter is described as:

An HttpApplication that provides access to the methods, properties, and events common to all application objects within an ASP.NET application

The key here is that there is one PageHttpModule for the lifetime of the app, and all static objects that exist in the lifetime of the app will share those variables.

BUT... the lifetime of CurrentUser is only within the scope of the OnAuthenticateRequest event, unless some other reference keeps the object alive. If it were a PageHttpModule member-level variable, you'd have issues that you would have noticed immediately. In your situation, however, you'll work fine so long as you don't get more than one simultaneously-processed OnAuthenticateRequest call.

The answer to your question is no, you're not guaranteed to be thread-safe. If two authentication requests come in simultaneously, you're not guaranteed to have one event complete before the other begins, in which case the second user can appear authenticated, when it's really the first user that was logged on.

Update
I think part of the problem is coming from a misunderstanding of AuthenticateRequest... By the time this event is called, the user has already been authenticated by either Windows or Forms authentication... you're just getting notified that it's happened. In fact, the property User.Identity.IsAuthenticated has already been set (I believe this event fires even if the user fails authentication, but I won't swear to that without double-checking).

If I understand what you are after, you're really trying to write your own custom membership provider. If you take this approach, you will have all the benefits of the built-in authentication... all of the standard properties related to authentication will be set and accessible, and will be isolated to a user's session in the manner you want.

Writing a custom provider is not a small feat, but it is doable, and you should be able to reuse a lot of the logic and code you're currently using for your classes.

Trying to completely re-write the authentication mechanism would be jumping through painful, complicated hoops.

Some links:
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

The properties you must implement may look daunting, but unless you need a specific functionality (such as ResetPassword), you can simply throw a NotImplementedException. Code only what you'll use.

残龙傲雪 2024-10-08 11:28:50

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

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

我已经通过这种方式完成了自定义身份验证,并且效果很好。


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

链接

Why not just do it the way microsoft recommends?

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

I've done custom authentication this way and it works fine.


Here is another link which should prove useful:

Link

在风中等你 2024-10-08 11:28:50

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

What you have done with IHttpModule seems like a good path to tackle this kind of issue. One of the purposes of the http module as stated by microsoft is to enable for any kind of special authentication. When http module intializes it uses the same instance for new requests. Since you dont have any global variables I am not so sure how to address your thread safe question. It seems like you are onlu reading some data out, so please elaborate!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文