Completely custom authentication in ASP.NET MVC: l

2019-06-20 11:24发布

问题:

I have my very own authentication system (https://bitbucket.org/anton_gogolev/octalforty-structural) which doesn't use any of the standard ASP.NET stuff (<authentication mode="None" />).

It uses plain IHttpModules to do its job: BeginRequest inspects incoming cookies and sets HttpContext.Current.User and Thread.CurrentPrincipal upon successful authentication

Thread.CurrentPrincipal = HttpContext.Current.User = 
    new GenericPrincipal(tokenIdentity,new string[] { });

whereas EndRequest issues all the required cookies for an authenticated user.

This has been working fine for months now, but on some systems (and I really cannot tell how are they different from ones this actually works on) ASP.NET seems to be losing the value of HttpContext.Current.User, replacing it with whatever default values there are (GenericPrincipal aggregating GenericIdentity with IsAuthenticated set to false, etc).

So the question is: how and why is HttpContext.Current.User getting lost?

回答1:

It sounds like there is another module that is modifying HttpContext.Current.User after BeginRequest. I would recommend setting it instead in PostAuthenticateRequest.

I've had this problem before with ASP.NET enabling the RoleManager module. Adding the following to the system.web section of web.config fixed it.

<httpModules>
     <remove name="RoleManager"/>
</httpModules>

Here's some amplifying information about what I did to fix this:

1) Figure out what other modules are running. Here's an article that provides some code for doing this.

2) Make sure you are setting HttpContext.Current.User in the correct place. BeginRequest isn't a good place to hook in. PostAuthenticateRequest is usually the best (and recommended). This won't prevent the problem if another module is also using PostAuthenticateRequest and it happens to be run after yours, but in many cases it will resolve the issue (use the web.config snippet above).

3) Selectively disable each installed module and test your application until your custom Principal object is not overwritten.