views:

92

answers:

2

Some Details

  • I am working with VisualWebGUI, so this app is like ASP.NET, and it is deployed on IIS 7 (for testing)
  • For my 'Web Site', Anonymous Authentication is set to a specific user (DomainName\DomainUser). In my web.config, I have impersonation on. This is how I got my app to access the share in the first place.

The Problem

There is a point in the the app where we use the Thread class, something similar to:

Thread myThread = new Thread(new ThreadStart(objInstance.PublicMethod));
myThread.Start();

What I have noticed is that I can write to my logs (text file on the share), everywhere throughout my code, except in the thread that I kicked off. I added some debugging output and what I see for users is:

  • The thread that's kicked off: NT AUTHORITY\NETWORK SERVICE
  • Everywhere else in my code: DomainName\DomainUser (described in my IIS setup)

OK, for some reason the thread gets a different user (NETWORK SERVICE). Fine. But, my share (and the actual log file) was given 'Full Control' to the NETWORK SERVICE user (this share resides on a different server than the one that my app is running).

If NETWORK SERVICE has rights to this folder, why do I get access denied? Or is there a way to have the thread I kick off have the same user as the process?

+2  A: 

NT AUTHORITY\NETWORK SERVICE is a local computer account. To the remote server it looks like your IIS computer's Active Directory account (COMPUTERNAME$). You need to grant access to the log directory to the AD Computer Account of your IIS box.

HTH

unclepaul84
That will give you access, but it is the wrong approach from a security point of view. It would be better to run the thread in the proper security context.
Luke
@Luke - I agree with you that the approach is questionable. But he was not asking for the right approach - only for the solution for a specific permissions problem.
unclepaul84
@uncluepaul84, thank you for your timely response (I upvoted your answer). I'm not the most "network-y" guy in the world, so your answer was englightening. Especially since I learned that these couple of servers in this test environment aren't even on a domain. So, granting access to each other is going to be a big PITA. I'm actually going to go with the other answer (for the green check-mark), but thanks again.
JustLooking
+2  A: 

You can also get the new thread to impersonate the user that issued the request. For example, if you are starting your request in the Page.Load event it might look like this.

  public partial class MyPage : System.Web.UI.Page
  { 
    protected void Page_Load(object sender, EventArgs e)
    {      
      Thread myThread = new Thread(new ParameterizedThreadStart(ThreadMethod));
      myThread.Start(HttpContext.Current.User); 
    }

    private void ThreadMethod(object state)
    {
      WindowsPrincipal principal = state as WindowsPrincipal;

      WindowsImpersonationContext impersonationContext = null;
      try
      {
        if (principal != null)
        {
          Thread.CurrentPrincipal = principal;
          impersonationContext = WindowsIdentity.Impersonate(((WindowsIdentity)principal.Identity).Token);
        }

        // Do your user specific stuff here...
      }
      finally
      {
        if (impersonationContext != null)
        {
          impersonationContext.Undo();
        }
      }
    }
  }

You will notice I passed the Principal from the ASP.NET thread through to the new thread, I obviously assume that you are using Windows Integrated Authentication so I did not do much in the way of error checking, this is just a quick sample.

Note: For VWG you would get the user from the VWG context and run the impersonation code in the appropriate function, this example is ASP.NET jsut because the environment is the same, just I do not know the VWG objects off the top of my head.

Chris Taylor
I think it would be more straightforward just to set the CurrentPrincipal property before actually starting the thread; that is pretty much what the original question was asking for. Basically newThread.CurrentPrincipal = currentThread.CurrentPrincipal.
Luke
@Luke, unfortunately you cannot set the CurrentPrincipal on the Thread instance, CurrentPrincipal is a static.
Chris Taylor
@Chris, thank you for your response. I've played around with my code (using code from your example), and everything is all good now. Green checkmark for you!
JustLooking
Doh, didn't realize that. I'm not a .NET guy :)
Luke