I'm working on an C# ASP.NET MVC application that runs on an intranet using Windows mode authentication with the following <system.web>
section in the Web.config
file:
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
<identity impersonate="true" />
</system.web>
I've created my own class that extends the AuthorizeAttribute
to do some processing based on the Windows account that connects. Within the overridden AuthorizeCore
function I grab the WindowsIdentity
object from HttpContextBase.User.Identity
and use it to pull data such as name, domain, etc. I then proceed to use this data to query certain records in my database and the result of this determines whether this function returns true or false. Upon returning false the browser pops-up a simple username and password box which allows the user to provide a different Windows account/password to use instead of the one the current user is logged in with.
A sample of how the AuthorizeCore
function looks in my project is the following:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
using (DbEntities dbContext = new DbEntities ())
{
bool authorize = allowedGroups.Length == 0;
string domainAndUserName = httpContext.User.Identity.Name;
int userNameIndex = domainAndUserName.IndexOf(@"\", StringComparison.OrdinalIgnoreCase) + 1;
string userName = domainAndUserName.Substring(userNameIndex);
try
{
// Process account and query database...
// set authorize to true if criteria met, otherwise false...
}
catch (EntityException ex)
{
authorize = false;
}
catch (SqlException ex)
{
authorize = false;
}
return authorize;
}
}
Let's assume that a user with Windows account USER_1 connects, the AuthrorizeCore
function then sets the domainAndUserName
variable to DOMAIN\USER_1
(as seen above), queries the database, and in the end determines that it isn't authorized. The username/password box appears and the user now inputs proper credentials for USER_2 which is authorized. The user now is able to access the requested resources. Now if the user closes the browser, re-opens it, and requests the resource (or a different one) the WindowsIdentity
that is pulled from the HttpContextBase
object seems to reference the older USER_2 account instead of the current USER_1 account (the domainAndUserName
variable ends up with a value of DOMAIN\USER_2
instead of DOMAIN\USER_1
).
It seems that if I wait a bit then it will use the USER_1 WindowsIdentity
so it would seem like some caching functionality at play but I haven't been able to verify or pinpoint that. I've done some searching online and have attempted disabling caching entirely on the IIS server as well as clearing the browser cache but I still encounter this scenario. Any help or guidance on how to always have the AuthorizeCore
function's HttpContextBase.User.Identity
always reference the current Windows account would be greatly appreciated.