UPDATE:
I solved this problem with just a few fairly simple changes, see my self-answer below.
ORIGINAL QUESTION:
I have an ASP.NET web app that uses both Windows authentication and Forms authentication. Forms
authentication is defined as the authentication mode
in Web.config (see below for excerpt). In IIS 7, at the web app (AKA virtual directory) level, anonymous authentication is disabled, and windows authentication is enabled.
In .NET 1.1 to .NET 4.0 and IIS6/7/7.5 after successfully authenticating via Windows auth, but before authenticating via Forms auth (creating the forms authentication ticket / cookie), Global.Application_AuthenticateRequest()
sees that Request.IsAuthenticated
is false
. And once Request.IsAuthenticated
becomes true
the System.Web.HttpContext.Current.User
is of type System.Security.Principal.GenericPrincipal
(and User.Identity
is System.Web.Security.FormsIdentity
)
This behavior changed after .NET 4.5 was installed on the IIS7 server. No changes were made to the Web.config file, and no changes were manually made to IIS. The only change I made was to install .NET 4.5. The behavior reverted back to 'normal' after uninstalling 4.5 and reinstalling 4.0.
The different behavior I noticed is that after successfully authenticating via Windows, but before authenticating via forms (the forms authentication ticket has not yet been created), Application_AuthenticateRequest
now shows that Request.IsAuthenticated
is true
.
Also, the System.Web.HttpContext.Current.User.Identity
is now System.Security.Principal.WindowsIdentity
(instead of FormsIdentity
).
- Can somebody please explain why this is different?
- Is there a configuration option (like web.config change or IIS setting) that I can use to force it to work the 4.0 way? (so that windows auth does not trump forms auth with respect to setting
Request.IsAuthenticated = true
?)
I have been searching Msft docs for hours.. all their info about mixing Windows and Forms auth seems to be years out of date (2004-ish), and the details on changes to .NET 4.5 are rather sparse in this particular area.
Excerpt from web.config: (yes, default.aspx is intentional, I don't use login.aspx in this case, but it has been working fine for 5+ years and across all previous .net versions).
<authentication mode="Forms">
<forms name=".ASPXAUTH" protection="All" timeout="200" loginUrl="default.aspx" defaultUrl="~/default.aspx" />
</authentication>
Excerpt from Global.asax.cs:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
// stuff for authenticated users
// prior to upgrading to .NET 4.5, this block was not hit until
// after the forms authentication ticket was created successfully
// (after validating user and password against app-specific database)
}
else
{
// stuff for unauthenticated users
// prior to upgrading to .NET 4.5, this block was hit
// AFTER windows auth passed but BEFORE forms auth passed
}
}