10

我正在使用 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 时,Application_AuthenticateRequest 似乎会在发出任何请求时触发(对于 JS 文件、图像等),这会导致应用程序死亡。

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

TIA。

4

2 回答 2

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 原则,或者至少使用与您的 SiteUser 类具有相同信息的自定义 IPrincipal/IUser 组合。

所以在 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 值,并且如果您愿意,支持使用机器密钥进行加密(如果已配置为这样做)。读取函数应验证这些值。

于 2009-10-14T09:14:01.940 回答
1

这听起来像是自定义 Authorization Filter的工作。

于 2009-10-13T10:23:04.560 回答