根据新请求,自定义主体恢复为 GenericPrincipal

发布于 2024-10-15 18:17:45 字数 401 浏览 6 评论 0原文

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

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

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

我是否需要做任何“额外”的事情才能使我的自定义主体脱离线程或 HttpContext?

谢谢

I'm trying to implement a custom principal and custom identity in a .NET MVC website. I've created a custom principal class which inherits from IPrincipal and a custom identity which inherits from IIdentity.

When a user logs in I set both Thread.CurrentPrincipal and HttpContext.Current.User to my custom principal. When I view either through the debugger the values are set with all the properties.

However once the request is complete and I try and request any other pages both Thread.CurrentPrincipal and HttpContext.Current.User are of type System.Security.Principal.GenericPrincipal and not my custom principal.

Do I need to do anything "extra" to get my custom principal out of the thread or HttpContext?

Thanks

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

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

发布评论

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

评论(3

陌路黄昏 2024-10-22 18:17:46

Thread.CurrentPrincipalHttpContext.Current.User 中的值不会在请求之间保留,而是在每个请求上重建。执行此操作的最佳位置可能是 Global.asax;使用原型编写一个函数:

void Application_PostAuthenticateRequest(object sender, EventArgs e)

在每个请求对用户进行身份验证后应该调用该函数,这将允许您按照自己的意愿设置主体。

The values in Thread.CurrentPrincipal and HttpContext.Current.User are not persisted between requests, they are rebuilt on each request. The best place for you to do this is probably in the Global.asax; write a function with the prototype:

void Application_PostAuthenticateRequest(object sender, EventArgs e)

That should get called after a user is authenticated on each request, which will allow you to set the principal how you would like.

清音悠歌 2024-10-22 18:17:46

重写主体:

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)

而不是

protected void Application_AuthenticateRequest(object sender, EventArgs e)

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

Overridding Principal in:

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)

Instead of

protected void Application_AuthenticateRequest(object sender, EventArgs e)

In Global.asax.cs worked for me in an ASP web application

梦中的蝴蝶 2024-10-22 18:17:46

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

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

我创建了一个简单的缓存接口 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< 的检查很重要/code>,因为在很多情况下我可以绕过缓存检查。您可能也不需要更新 Thread.CurrentPrincipal ,我想这取决于您如何使用它。

I would like to expand on the accepted answer slightly, hopefully I can save somebody a little bit of time.

In my case, the principal I used contained claims that were populated from the results of an external service, so I wanted to cache the results at login time.

I created a simple cache interface, IUserPrincipalCache, and registered it with the MVC DependencyResolver. At login, I build up the principal and add it to the cache. (Since your implementation may vary, I'll leave all that out.)

I then implemented this in 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;
        }
    }
}

I think it is important to point out the check for IsAuthenticated, since I could bypass the cache check in many cases. You also may not need to update Thread.CurrentPrincipal, I guess that depends on how you're using it.

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