在 ASP.net 应用程序中,我将登录控件与我编写的自定义成员资格提供程序一起使用。我想要做的是在用户通过身份验证后将 Thread.CurrentPrincipal 设置为我的自定义主体对象。
我正在使用 setter :Thread.CurrentPrincipal
,它为我设置了主体对象,但是,在所有后续线程上,此 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 硬编码用户,该对象设置为我设置为的主体对象 CurrentPrincipal
对象。
当我在此方法结束时检查哪个用户设置为 CurrentPrincipal
身份时,它说它是用户 B。但是当我加载另一个页面,然后检查 的身份时CurrentPrincipal
是,它说它是用户 A。
那么,如何使我的 CurrentPrincipal
对象在所有其他线程中持久存在,以及此登录控件在何处/何时设置线程的 CurrentPrincipal
对象?
最佳答案
Tadas 没有错,正确实现的 FormsAuthentication 不会导致此问题。
即使没有登录,您的页面也可以访问,仅在登录页面中,您的线程原理是由您手动设置的,但是当您点击其他URL时,它肯定不会调用您的登录页面,并且记住每个页面都在其自己不同的上运行线。如果您请求第一页并设置线程原则,并且您在同一浏览器实例中请求第二页,则它可能是也可能不是完全相同的线程。
这就是 FormsAuthentication 的工作原理,
- 它检查是否设置了 Auth Cookie,然后引导用户访问登录页面
- 登录页面必须验证并设置身份验证 cookie,例如 FormsAuthentication.SetAuthCookie
- 每次访问页面之前,都会执行第 1 步。
- 成功验证 Auth Cookie 后,ASP.NET 会根据您的成员资格组件在内部设置当前用户和所有不同的网络参数。
- ASP.NET Global.asax 文件可以为您提供一些事件,您可以在其中插入代码以在身份验证成功后进行检查,您可以更改当前用户,请记住在登录页面上设置当前原则不会有帮助
当我们使用 session 存储某些重要信息时,在未重建身份验证 session 后,我们遇到了类似的问题,因此我们编写了一个 HTTP 模块,并在其 init 方法中,我们附加了 AfterRequestAcquired 事件,在这种情况下,您可以编写您的用于实例化所有重要的用户相关变量的代码。
关于asp.net - 如何设置 Thread.CurrentPrincipal 以在整个应用程序中使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1356449/