自定义主体在新请求时恢复为GenericPrincipal

时间:2011-02-03 17:08:03

标签: asp.net asp.net-mvc security iprincipal

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

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

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

我是否需要做任何“额外”操作才能将我的自定义主体从线程或HttpContext中删除?

由于

3 个答案:

答案 0 :(得分:6)

Thread.CurrentPrincipalHttpContext.Current.User中的值不会在请求之间保留,它们会在每个请求中重建。你最好的地方可能在Global.asax;用原型写一个函数:

void Application_PostAuthenticateRequest(object sender, EventArgs e)

在每个请求上对用户进行身份验证后,应该调用它,这样您就可以根据需要设置主体。

答案 1 :(得分:0)

覆盖原则:

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)

而不是

protected void Application_AuthenticateRequest(object sender, EventArgs e)

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

答案 2 :(得分:0)

我想略微扩展已接受的答案,希望我可以节省一些时间。

在我的情况下,我使用的主体包含从外部服务的结果填充的声明,所以我想在登录时缓存结果。

我创建了一个简单的缓存接口IUserPrincipalCache,并将其注册到MVC DependencyResolver。登录时,我构建了主体并将其添加到缓存中。 (由于您的实施可能会有所不同,我将把所有这些都留下来。)

然后我在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,我想这取决于您如何使用它。