Forms Authentication cross Windows Authentication

2020-03-05 06:46发布

问题:

I have a website that I am working on that has both an intranet and internet deployment. The only difference between the 2 is a couple of config settings.

The internet version works fine as it just uses forms authentication (which is defined in its web config) and if not logged in the user is directed to a login page.

The intranet version is a little trickier... when a user first comes to the site the http context principle object is set correctly with WindowsPrincipal, but using that information I confirm that the user is allowed access to the app and then I create my own IPrinciple instance.

Given this there are a couple of things I want to do here... I want to use the WindowsPrincipal object as a basis for authenticating the user but then from that point forward use forms authentication (i.e. using a cookie to store the auth details etc). I also need the instance of the principle that I retrieve from the HTTP context to be of my IPrinciple type.

How am I best to go about doing this? As in should I look to the global.asax's Session_Start to perform auth logic and then somehow get it to store my custom IPrinciple (so for any request after that point the instance is my custom principle) or am I best to be doing something with Application_AuthenticateRequest.

Cheers Anthony

回答1:

Avoid the session object for this. Application_AuthenticateRequest is where you want to be. In there, you can take the WindowsPrincipal, and then go to the database to populate your own custom IPrincipal-implementing object. This means that Application_AuthenticateRequest gets called a lot, though, so in my apps, I tend to cache the role data for at least a few seconds to cut down on database round trips. This also works with Forms authentication. The only difference between the two methods is that in the Forms scenario, you get a GenericPrincipal from the Forms auth module, and you'd use that to retrieve your own custom principal object instead of the WindowsPrincipal.

Another upshot of setting HttpContext.Current.User in Application_AuthenticateRequest is that, unlike if you put your principal in the Session object, you can use declarative security, such as decorating your methods with PrincipalPermissionAttribute.