4

我正在尝试在 .NET MVC 网站中实现自定义主体和自定义标识。我创建了一个继承自 IPrincipal 的自定义主体类和一个继承自 IIdentity 的自定义身份。

当用户登录时,我将 Thread.CurrentPrincipal 和 HttpContext.Current.User 都设置为我的自定义主体。当我通过调试器查看时,值是使用所有属性设置的。

但是,一旦请求完成并且我尝试请求任何其他页面,Thread.CurrentPrincipal 和 HttpContext.Current.User 的类型都是 System.Security.Principal.GenericPrincipal 而不是我的自定义主体。

我需要做任何“额外”的事情来让我的自定义主体脱离线程或 HttpContext 吗?

谢谢

4

3 回答 3

6

Thread.CurrentPrincipal和中的值HttpContext.Current.User不会在请求之间持久化,它们会在每个请求上重建。最好的地方可能是 Global.asax;用原型写一个函数:

void Application_PostAuthenticateRequest(object sender, EventArgs e)

这应该在用户对每个请求进行身份验证后调用,这将允许您根据需要设置主体。

于 2011-02-03T18:22:20.960 回答
0

覆盖主体:

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)

代替

protected void Application_AuthenticateRequest(object sender, EventArgs e)

在 Global.asax.cs 中为我工作的 ASP Web 应用程序

于 2013-10-22T15:01:56.960 回答
0

我想稍微扩展已接受的答案,希望我可以为某人节省一点时间。

就我而言,我使用的主体包含从外部服务的结果中填充的声明,因此我想在登录时缓存结果。

我创建了一个简单的缓存接口,IUserPrincipalCache并将其注册到 MVCDependencyResolver中。登录时,我建立主体并将其添加到缓存中。(由于您的实现可能会有所不同,因此我将省略所有这些。)

然后我在Global.asax.cs

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
    if (User.Identity.IsAuthenticated)
    {
        var cache = DependencyResolver.Current.GetService<IUserPrincipalCache>();
        var claimsPrincipal = cache.FindUser(User.Identity.Name);
        if (claimsPrincipal != null)
        {
            Context.User = claimsPrincipal;
            Thread.CurrentPrincipal = claimsPrincipal;
        }
    }
}

我认为指出检查很重要IsAuthenticated,因为在许多情况下我可以绕过缓存检查。你也可能不需要更新Thread.CurrentPrincipal,我想这取决于你如何使用它。

于 2015-04-21T20:51:52.393 回答