ASP.NET MVC自定义IPrincipal注入

时间:2009-10-12 15:07:08

标签: asp.net-mvc iprincipal

我正在使用ASP.NET MVC 1.0开发应用程序,我正在尝试将自定义IPrincipal对象注入HttpContext.Current.User对象。

使用传统的WebForms应用程序,我使用Application_AuthenticateRequest事件执行此操作,如下所示。

protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    // Get Forms Identity From Current User
                    FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
                    // Get Forms Ticket From Identity object
                    FormsAuthenticationTicket ticket = id.Ticket;
                    // Create a new Generic Principal Instance and assign to Current User
                    SiteUser siteUser = new SiteUser(Convert.ToInt32(id.Name));

                    HttpContext.Current.User = siteUser;
                }
            }
        }

    }

因此,通过显式转换User对象以键入SiteUser,我可以访问我的自定义IPrincipal。我实际上通过一个自定义类来实现这一点,所有的Pages都是继承自我的。

无论如何,我的问题是,使用ASP.NET MVC时,每当发出任何请求(因此对于JS文件,图像等)时,Application_AuthenticateRequest似乎都会触发,这会导致应用程序死亡。

关于如何将自定义IPrincipal注入ASP.NET MVC 1.0中的HttpContext.Current.User对象的任何帮助或建议将不胜感激。我确实在SO上看到了以下帖子,但它似乎并不适合我想要实现的目标:ASP.NET MVC - Set custom IIdentity or IPrincipal

TIA。

2 个答案:

答案 0 :(得分:8)

  

我的问题是ASP.NET MVC   Application_AuthenticateRequest   似乎任何请求都会触发   制作(因此对于JS文件,图像等)   导致应用程序死亡。

这不是一个独特的MVC问题 - 如果您在IIS7上使用集成管道运行应用程序,那么您会看到同样的事情。

如果查找问题是可伸缩性,那么我认为实际问题在

之内
FormsAuthenticationTicket ticket = id.Ticket;
SiteUser siteUser = new SiteUser(Convert.ToInt32(id.Name));

我猜你的SiteUser类会进行某种数据库查找。如果您检查表单身份验证的工作方式,则故障单包含生成FormsIdentity所需的所有信息(这不适用于角色,除非您专门启用角色缓存到cookie)。所以你应该看看同样的方法。第一次构建siteUser对象时,将其缓存在已签名的cookie中,然后使用cookie在后续请求中为您的SiteUser属性重新水化。

如果你这样做,那么你可以更进一步,用你的SiteUser取代Thread原则,或至少一个自定义IPrincipal / IUser组合,它与你的SiteUser类具有相同的信息。

所以在AuthenticateRequest中你会有一些像

这样的流程
SiteUserSecurityToken sessionToken = null;
if (TryReadSiteUserSecurityToken(ref sessionToken) && sessionToken != null)
{
    // Call functions to attach my principal.
}
else
{
    if (HttpContext.Current.User != null && 
        HttpContext.Current.User.Identity.IsAuthenticated && 
        HttpContext.Current.User.Identity is FormsIdentity)
    {
        // Get my SiteUser object

        // Create SiteUserSecurityToken

        // Call functions to attach my principal.
    }
}

附加主体的功能将包含类似

的功能
HttpContext.Current.User = sessionSecurityToken.ClaimsPrincipal;
Thread.CurrentPrincipal = sessionSecurityToken.ClaimsPrincipal;
this.ContextSessionSecurityToken = sessionSecurityToken;

您需要确保将安全令牌写入cookie的功能至少添加校验和/ MAC值,如果您愿意,还可以使用机器密钥支持加密(如果配置为执行此操作)所以。读取函数应验证这些值。

答案 1 :(得分:1)

这听起来像custom Authorization Filter的工作。