我正在尝试在.NET MVC网站中实现自定义主体和自定义标识。我创建了一个自定义主体类,它继承自IPrincipal和继承自IIdentity的自定义标识。
当用户登录时,我将Thread.CurrentPrincipal和HttpContext.Current.User设置为我的自定义主体。当我通过调试器查看时,使用所有属性设置值。
但是,一旦请求完成,我尝试并请求任何其他页面,Thread.CurrentPrincipal和HttpContext.Current.User的类型为System.Security.Principal.GenericPrincipal,而不是我的自定义主体。
我是否需要做任何“额外”操作才能将我的自定义主体从线程或HttpContext中删除?
由于
答案 0 :(得分:6)
Thread.CurrentPrincipal
和HttpContext.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
,我想这取决于您如何使用它。