【问题标题】:How to set Thread.CurrentPrincipal for use throughout the application?如何设置 Thread.CurrentPrincipal 以在整个应用程序中使用?
【发布时间】:2009-08-31 08:32:41
【问题描述】:

在一个 ASP.net 应用程序中,我正在使用带有我编写的自定义成员资格提供程序的登录控件。我要做的是在用户通过身份验证后将Thread.CurrentPrincipal 设置为我的自定义主体对象。

我正在使用 setter:Thread.CurrentPrincipal,它为我设置了 Principal 对象,但是在所有后续线程上,此 CurrentPrincipal 被默认值覆盖。

这是我的登录控件的身份验证事件的代码:

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
    {
        string username = Login1.UserName;
        string password = Login1.Password;

        if (Membership.ValidateUser(username, password))
        {
            var login = sender as Login;
            var phoenixIdentity = new PhoenixIdentity("B", "Forms" , true);
            var principal = new PhoenixPrincipal(phoenixIdentity);

            Thread.CurrentPrincipal = principal;
            AppDomain.CurrentDomain.SetThreadPrincipal(principal);

            HttpContext.Current.User = principal;

            e.Authenticated = true;
        }
    }

例如,假设我使用用户名 A 登录,一切顺利...验证通过,但我在 Identity 对象中使用用户名 B 对用户进行硬编码,该对象设置为我设置为 @987654324 的 Principal 对象@对象。

当我在此方法的末尾检查哪个用户设置为 CurrentPrincipal 身份时,它说它是用户 B。但是当我加载另一个页面然后检查 CurrentPrincipal 的身份时,它说它是用户 A。

那么,我怎样才能使我的CurrentPrincipal 对象在所有其他线程中保持不变,以及此登录控件在何处/何时设置线程的CurrentPrincipal 对象?

【问题讨论】:

  • 你在做什么?您希望每个人都被识别为第一个登录用户吗?您需要了解 Web 应用程序的认证和授权机制、cookie 的使用等。您不能将一个主体设置为所有多用户应用程序线程。
  • 当然不是。可能我表达的不够清楚。

标签: asp.net authentication identity principal


【解决方案1】:

Tadas 没有错,FormsAuthentication 正确实现不会出现这个问题。

即使没有登录也可以访问您的页面,仅在登录页面中,您的线程的原理是由您手动设置的,但是当您点击另一个 URL 时,它肯定不会调用您的登录页面并记住每个页面运行在自己的不同线。如果您请求第一页并设置线程原则,并且您在同一浏览器实例中请求第二页,它可能是也可能不是完全相同的线程。

这就是 FormsAuthentication 的工作原理,

  1. 它检查是否设置了 Auth Cookie,然后将用户引导到登录页面
  2. 登录页面必须验证并设置身份验证cookie,如FormsAuthentication.SetAuthCookie
  3. 在每次访问页面之前,都会执行第 1 步。
  4. Auth Cookie 验证成功后,ASP.NET 会根据您的成员资格组件在内部设置当前用户和所有不同的参数。
  5. ASP.NET Global.asax 文件可以为您提供一些事件,您可以在其中插入代码以在身份验证成功后检查您可以更改当前用户,记住在登录页面上设置您当前的原则将无济于事

我们在使用 session 存储某些重要信息时遇到了类似的问题,在 auth 会话没有重建之后,所以我们编写了一个 HTTP 模块,在它的 init 方法中,我们附加了 AfterRequestAcquired 事件,在这种情况下你可以编写你的实例化所有重要的用户相关变量的代码。

【讨论】:

    【解决方案2】:

    您可以处理 FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e)(在 Global.asax 中)并在此处设置 CurrentPrincipal。

    
    void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e)
    {
    var phoenixIdentity = new PhoenixIdentity("B", "Forms" , true);
    var principal = new PhoenixPrincipal(phoenixIdentity);
    e.User = principal;
    }
    

    【讨论】:

    • 让我再澄清一下...如果您没有注意到,我已经在使用表单身份验证...只是我想保留用户 ID(以及其他一些用户信息)在 Thread.CurrentPrincipal 的 Identity 对象中,所以我实现了自己的 Principal 和 Identity 对象,并覆盖了表单身​​份验证的 Login 控件的 Authenticate 方法。
    【解决方案3】:

    这是我在 FormsAuthentication_OnAuthenticate 方法中所做的:

    if (FormsAuthentication.CookiesSupported)
            {
                if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
                {
                    try
                    {
                        FormsAuthenticationTicket ticket = 
                            FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value);
    
                        var myIdentity = new GenericIdentity("B");
                        var principal = new GenericPrincipal(myIdentity, new string[]{"rola1"});
                        e.User = principal;
                    }
                    catch (Exception ex)
                    {
                        // Decrypt method failed.
                    }
                }
            }
            else
            {
                throw new HttpException("Cookieless Forms Authentication is not " +
                                        "supported for this application.");
            }
    

    它似乎正在发挥它应该做的工作......只是如果我将我的自定义主体/身份对设置为 e.User,那么我有序列化问题,我需要接下来解决......谢谢你们。 ..

    【讨论】:

    • 当我切换到 IIS 而不是使用 Visual Studio 开发服务器时,序列化问题就消失了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多