ASP.NET MVC custom IPrincipal injection

旧城冷巷雨未停 提交于 2019-12-02 18:33:55
blowdart

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.

bzlm

This sounds like a job for a custom Authorization Filter.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!