ASP.NET MVC自定义的IPrincipal注入 [英] ASP.NET MVC custom IPrincipal injection

查看:476
本文介绍了ASP.NET MVC自定义的IPrincipal注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个应用程序中使用ASP.NET MVC 1.0工作,我试图注入一个自定义IPrincipal对象到HttpContext.Current.User对象。

通过传统的WebForms应用程序,我已经使用了Application_AuthenticateRequest事件要做到这一点如下:

 保护无效Application_AuthenticateRequest(对象发件人,EventArgs的发送)
    {
        如果(HttpContext.Current.User!= NULL)
        {
            如果(HttpContext.Current.User.Identity.IsAuthenticated)
            {
                如果(HttpContext.Current.User.Identity是FormsIdentity)
                {
                    //获取表单的身份从当前用户
                    FormsIdentity ID =(FormsIdentity)HttpContext.Current.User.Identity;
                    //获取表单门票从身份对象
                    的FormsAuthenticationTicket票= id.Ticket;
                    //创建一个新的通用主体实例,并分配给当前用户
                    SiteUser siteUser =新SiteUser(Convert.ToInt32(id.Name));                    HttpContext.Current.User = siteUser;
                }
            }
        }    }

所以使用这个我能够通过显式铸造用户对象键入SiteUser访问我的自定义的IPrincipal。我实际上是由具有的所有页面都从这样做的封面,我下继承的自定义类这样做。

不管怎样,我的问题是,与ASP.NET MVC的Application_AuthenticateRequest似乎火,只要任何请求时(因此对于JS文件,图像等),这会导致应用程序死掉。

任何帮助或建议,我怎么可以去ASP.NET MVC 1.0之内注入我的自定义的IPrincipal到HttpContext.Current.User对象将大大AP preciated。我没有看到所以下面的职位,但它似乎并没有满足我想要实现:<一href=\"http://stackoverflow.com/questions/1064271/asp-net-mvc-set-custom-iidentity-or-iprincipal\">http://stackoverflow.com/questions/1064271/asp-net-mvc-set-custom-iidentity-or-iprincipal

TIA。


解决方案

  

我的问题是,与ASP.NET MVC
  在Application_AuthenticateRequest
  似乎只要火任何请求
  做(所以对于JS文件,图像等)
  这会导致应用程序终止。


这是不是唯一的问题MVC - 如果你在​​的地方综合管线IIS7上运行你的应用程序,那么你会看到同样的事情

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

 的FormsAuthenticationTicket票= id.Ticket;
SiteUser siteUser =新SiteUser(Convert.ToInt32(id.Name));

我猜你SiteUser类做了某种数据库查询的。如果你研究如何窗体身份验证的工作票包含所有必要产生FormsIdentity的信息(这不适合角色的持有真实的,除非您特别使角色缓存到一个cookie)。所以,你应该看看同样的做法。当您第一次构建您siteUser对象缓存一个签名cookie中,然后使用cookie来对后续请求您补充水分的属性SiteUser。

如果你这样做,那么你可以走一步,你的SiteUser更换主题的原则,或至少具有相同的信息作为你的SiteUser类将有一个自定义的IPrincipal / IUSER组合。

所以里面的AuthenticateRequest你不得不像一些流程

  SiteUserSecurityToken sessionToken = NULL;
如果(TryReadSiteUserSecurityToken(REF sessionToken)及和放大器;!sessionToken = NULL)
{
    //调用功能,附上我的校长。
}
其他
{
    如果(HttpContext.Current.User = NULL&放大器;!&安培;
        HttpContext.Current.User.Identity.IsAuthenticated&功放;&安培;
        HttpContext.Current.User.Identity是FormsIdentity)
    {
        //获取我的SiteUser对象        //创建SiteUserSecurityToken        //调用功能,附上我的校长。
    }
}

和附加主要将包含类似

功能

  HttpContext.Current.User = sessionSecurityToken.ClaimsPrincipal;
= Thread.CurrentPrincipal中sessionSecurityToken.ClaimsPrincipal;
this.ContextSessionSecurityToken = sessionSecurityToken;

您将使用计算机密钥,如果它的配置做想确保它编写安全令牌,以一个cookie的功能添加,至少,校验/ MAC值,而且,如果你喜欢,支持加密所以。读取的功能应该验证这些值。

I'm working on an application using ASP.NET MVC 1.0 and I'm trying to inject a custom IPrincipal object in to the HttpContext.Current.User object.

With a traditional WebForms application I've used the Application_AuthenticateRequest event to do this as follows.

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;
                }
            }
        }

    }

So using this I was able to access my custom IPrincipal by either explicitly casting the User object to type SiteUser. I actually did this by having a custom class that all Pages were inheriting from which did this under the covers for me.

Anyhow, my problem is that with ASP.NET MVC the Application_AuthenticateRequest seems to fire whenever any request is made (so for JS files, images etc.) which causes the application to die.

Any help or suggestions as to how I can go about injecting my custom IPrincipal in to the HttpContext.Current.User object within ASP.NET MVC 1.0 would be greatly appreciated. I did see the following post on SO, but it didn't seem to cater for what I'm trying to achieve: http://stackoverflow.com/questions/1064271/asp-net-mvc-set-custom-iidentity-or-iprincipal

TIA.

解决方案

my problem is that with ASP.NET MVC the Application_AuthenticateRequest seems to fire whenever any request is made (so for JS files, images etc.) which causes the application to die.

This isn't an uniquely MVC problem - if you ran your application on IIS7 with the integrated pipeline in place then you would see the same thing.

If the problem with the lookup is scalability then I assume the actual problem is within

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

I'd guess that your SiteUser class does some sort of database lookup. If you examine how forms auth works the ticket contains all the information necessary to produce a FormsIdentity (this doesn't hold true for roles, unless you specifically enable roles caching to a cookie). So you ought to look at the same approach. The first time you construct your siteUser object cache it within a signed cookie, then use the cookie to rehydrate your SiteUser properties on subsequent requests.

If you do this then you can go one step further, replacing the Thread principle with your SiteUser, or at least a custom IPrincipal/IUser combination which has the same information as your SiteUser class would have.

So inside AuthenticateRequest you'd have some flow like

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.
    }
}

And the function to attach the principal would contain something like

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

You'll want to make sure that the functions which write the Security Token to a cookie add, at a minimum, a checksum/MAC value, and, if you like, support encryption using the machine key if it's configured to do so. The read functions should validate these values.

这篇关于ASP.NET MVC自定义的IPrincipal注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆