3

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.

Fizz
  • 3,427
  • 4
  • 27
  • 43
  • Are you using session in your application? Can it be related to session? Have you tried to disable session? – Andrii Litvinov Apr 17 '17 at 14:11
  • As far as I understand, I don't do any specific logic to setup any kind of session. – Fizz Apr 17 '17 at 14:20
  • 1
    I can't help with your specific question, but there are a number of things I would suggest you change about your approach. First, you shouldn't be doing database queries within the attribute. The attribute should merely have the logic to determine authorization based on previous queries performed during the page initialization. Second, you should not use attributes and web.config based authentication at the same time. In fact, web.config based authorization is considered a no-no in MVC applications and you should rely only on attribute based methods. – Erik Funkenbusch Apr 17 '17 at 14:26
  • 2
    Finally, you are probably misusing identity impersonate as well. This probably doesn't do what you think it does. In fact, you can't even use it with integrated pipeline mode in IIS (you must have selected classic pipeline somewhere). You generally shouldn't use classic mode unless you have legacy code that requires it, since this mode will likely go away eventually. – Erik Funkenbusch Apr 17 '17 at 14:28
  • I understand your comment about not doing a DB query within the attribute and I could move that logic elsewhere. As for the web.config based authentication, I have a requirement that this must use Windows Authentication although I suppose I could check if the `WindowsIdentity`is authenticated in the attribute. As per your 2nd comment, I'm not clear exactly what you mean. I need the impersonate flag to make certain scenarios and DB calls simpler and possible. – Fizz Apr 17 '17 at 14:31
  • I suggest you read this http://stackoverflow.com/a/22692556/61164 and https://blogs.msdn.microsoft.com/autz_auth_stuff/2011/05/14/windowsimpersonationcontext/ – Erik Funkenbusch Apr 17 '17 at 14:54
  • I'll take a look but I should mention that I have the `validateIntegratedModeConfiguration` flag set to `false`. I forgot about this change until just now and it might change the scenario a bit. – Fizz Apr 17 '17 at 15:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/141899/discussion-between-fizz-and-erik-funkenbusch). – Fizz Apr 17 '17 at 15:05
  • Although I haven't verified the whether information provided will address my issue, my gut tells me that I'll find a solution using the provided solution. Feel free to create a solution with the information provided and I'll accept it. – Fizz Apr 17 '17 at 15:56
  • Well, I don't consider these solutions to your problem, just additional help. Maybe someone else will chime in with something more, as I don't really have the time for a decent answer. Also, I was talking about the authorization section of your web.config, not the authentication element. Authorization and Authentication are two separate things. You shouldn't be using an authorization element in web.config – Erik Funkenbusch Apr 17 '17 at 16:32
  • Have you considered cookies? Take a look here especially from line 102. https://www.codeproject.com/articles/533989/extendingplustheplusbehaviorplusofplusmvcplusautho – Igor Apr 19 '17 at 10:03
  • Just adding another observation, this behavior seems much more problematic on Windows 10 than Windows 7. – Fizz May 10 '17 at 14:15

1 Answers1

-1

You can try using .current

HttpContext.Current.User.Identity.Name  
Rishi Shah
  • 46
  • 6