I have an ASP.NET website (in C#) that takes in user data and then attempts to create a windows scheduled task. Of course, this works great on the DEV machine, but fails to run on the server. I'm trying to figure out what permission(s) are required on the ASPNET user (or anonymous web user) to create tasks.
The error is:
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
Stacktrace:
at MyScheduler.NewWorkItem(String TaskName, Guid& rclsid, Guid& riid, Object& obj)
at MyScheduler.CreateTask(String name)
I've done some searching, and the suggested resolution is to use the web.config 'impersonate' flag to force the application to run as a user with sufficient permissions, as opposed to the ASPNET account which may not have those permissions.
Example:
<system.web>
<identity impersonate="true" />
</system.web>
Unfortunately, this does not seem to resolve the issue. From the documentation I read, this should run as the anonymous web user, but it seems that user does not have enough permissions.
I altered the setting to specify a specific domain user that happens to be an administrator on the machine. Example:
<system.web>
<identity impersonate="true" userName="WindowsDomain\YourUserName" password="YourPassword" />
</system.web>
Doing this allowed the application to successfully create the Windows Scheduled Task. So, obviously, with the correct set of Windows 2003 permissions I can get the app to perform as it does in the development environment. However, I'm not about to place the network or machine administrator account's user credentials in plain text on a Web.config file.
Does anybody happen to know what permissions exactly need to be set in order to get the ASPNET account to behave as desired?
EDIT: The Win32 API is being used to create scheduled tasks.
Instead of worrying about the ASPNET user permissions, would your internal process allow you to create a machine specific account and supply the credentials there?
I have been able to solve my particular problem, though not completely. I have still not identified the exact rights needed to create and run scheduled tasks, but the following seems to work:
Add the <identity impersonate="true" /> to the Web.config
Add the IUSR user (which is the user the app will run as using impersonate) to the "Backup Operators" group.
This gives the application access to the Scheduled Tasks folder so that they can create and run the task.
We had an additional issue, which was that the tasks were attempting to run as the Local System Account. Unfortunately, only administrators seem to be able to assign the Local System Account as the running user, so we needed to impersonate as an Administrator account, not as a Backup Operator in order to get our code functioning correctly.
Are you writing something to the eventlog ?
It is possible that your component (which is hosted in IIS i presume ? ) has no access to the write something in the eventlog.
This is merely a guess ~ a while ago, I've been faced with a similar problem, and I've solved it in this way:
Click
Another option is to flash the bios on the server
Related
I have an MVC web application that is supposed to allow users to download files that are stored as UNC paths in a database. These files can be in any number of locations on remote servers/shares.
E.g. Server 1 hosts the web application that is used to download a file stored on Server 2
I do not want to give permissions to these folders to the hosting service account, as the security should be dependent on what the user has access to. Therefore, I'm attempting to use Impersonation to retrieve the file.
When I debug on my local machine, everything works great. It impersonates my user and downloads the file.
When I deploy to my test server, I'm getting the following error:
Access to the path '\\Server2\SharedFolder\somefile.txt' is denied
I've tried various pieces from this Microsoft link, but am not having much luck.
Scenarios I've tried:
Just giving the permission to the service account of the AppPool works fine, but as I said, isn't ideal
Implementing the Impersonate a Specific User in Code from the above article, which works perfectly with a hard-coded user and password. This situation is also not ideal.
Implementing the Impersonate the Authenticating User in Code from the above article. This seems to be exactly what I need, but this is what generates the Access Denied error.
The Code that I want to work:
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Code to read all bytes from the file path
impersonationContext.Undo();
I have logging, and System.Security.Principal.WindowsIdentity.GetCurrent().Name after the impersonation does return the intended user (my account instead of the service account), so it does appear to be working.
I thought maybe it was a double-hop thing, so I have also added SPNs for the server and the service account, making sure their Delegation in AD was set to allow for any service. That hasn't helped either.
This question seems to have the exact same problem as me, but there's no follow-up on what the final solution was. I did try the Process Monitor part, but it didn't help at all.
I'm at a loss to why Impersonation seems to be working, but I'm denied access to a file on a second server.
Update 1
I've played around more with my IIS settings and trying to get Kerberos properly set up. The only thing enabled in my IIS Authentication is "Windows Authentication".
When I spit out details after my Impersonate() call, I'm finding that ImpersonationLevel = Impersonation
Is that how it should be, or should that be returning Delegation ?
It would seem the issue was mostly due to my setup with Kerberos and SPNs. I undid all my settings and re-registered my service account, and the Impersonation ended up working properly.
The issue now is that it only seems to work with Internet Explorer. Chrome and MobileIron are doing something different that prevents the ImpersonationLevel of Delegation. That's a whole other question...
In my Website, Users who has logged in are able to change their profile pictures, and this process includes saving the uploaded image to a folder in the website's root directory.
When I tested it, I received an Error that I should grant access to this specific folder using permissions.
I do not have control over the Control Panel, the one who does said that he did grant the Images folder a READ and WRITE permissions to Others.
After Testing it again, once again the same error, so I edited web.config and included:
<identity impersonate="true"/>
And now everything seems to work perfectly. BUT, what did I just do here? Is there any security risk? Did I grant anonymous access to my website for everyone?
BUT, what did I just do here?
You are now running your website under the identity of the client user.
Is there any security risk?
That would depend on the permissions that this account has on the server. Usually it is bad practice to run a website with accounts that have lots of privileges. Ideally you should configure your website to run under an account that you explicitly grant privileges to the required folders.
The problem with your approach is that if another user that doesn't have access to the specified folder visits your website, it won't work for him. If on the other hand this is expected behavior then you are probably fine by impersonating user identities.
Did I grant anonymous access to my website for everyone?
No, this has nothing to do with authentication.
What you have done is given user rights to work under logged in user.
And there is a security risk for making impersonate true.
If you are on production, I would recommend you to read this article
http://support.microsoft.com/default.aspx?scid=kb;en-us;329290
"Using impersonation in the web.config allows you to override whatever identity was configured for the Application Pool the app is running under - it's just a more fine grained method to control identity ( on the app level vs. the ApplicationPool level), so you could have two apps run on the same AppPool, but one of them uses impersonation to use another identity."
courtesy: App pool identity versus impersonation identity?
I get an UnauthorizedAccessException everytime I try to access (just read) a file on a network share "\\server\folder1\folder2\file.pdf."
I am impersonating the domain\aspnet user which has read & write access to the above mentioned folders. The file is not read-only.
I tried finding the permissions via System.Security.Permissions.FileIOPermission. It just says NoAccess to all files.
I'm not sure what else I can do.
I am using Visual Studio 2008, ASP.net 2.0 on Framework 3.5, WinXP, IIS 5.1.
ASP.NET user will not work with network path. So you need to have a windows account that
will have all the rights and then you need to imposernate things in web.config like following.
<identity impersonate="true" userName="domainname\windowuseraccount" password="password"/>
I'll assume you have set up the impersonation properly. You have turned off anonymous access, set the authentication mode to Windows and set impersonation to true, etc.
Even with all that done properly and the correct account impersonating you will still not be able to access the file. The account being impersonated is using what are called network credentials. These are only valid on the machine on which the impersonation is taking place. When you attempt to access a file on the computer itself the access is performed with the user's credentials but for a file on a share the access is done as a non-authenticated user and so no access is allowed.
In order to allow you to use the user's credentials for remote work, i.e. accessing a share, integrated security for a remote database, etc. you need to use delegation rather than impersonation. This is a somewhat complicated topic involving your Active Directory set-up and your IIS configuration. Have a look at this article, it should give you a good place to start.
Make sure that the domain user has Security rights and Share rights. That is, on the shared folder, add the domain user under the "Sharing" tab in the properties, as wells as under the "Security" tab.
What IIS version are you using? If it is version 6, you can place the web app in it's own application pool, then set the identity of that application pool to be a domain user account. Then, grant that domain user account access to the network share.
FYI you can place the following in an aspx file to verify what identify your pages are running as:
<%# Page Language="C#" %>
<% Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name); %>
To access a network share the above user will need to be a domain account setup by a network administrator.
I have a web service using .net c# and I want to write to a text file on the server, but I cannot get this to work. I believe it's a permission problem.
Specifically, I think the problem is I am using System.IO.Directory.GetCurrentDirectory().
Is there a better alternative?
Try granting the ASP.NET user (or whatever account IIS is running as) permission to write to the folder you are trying to write to.
If this is a network share, try to run IIS as a domain user that can write to the share.
Remember the principle of granting minimal permission (dont use Admin level access).
If you don't specify a destination folder I assume your web service wants to write to "C:\Windows\System32\" or something of that kind. That's why a UnauthorizedAccessException will be thrown on the server. In order to write to the "home"-directory of the web service you have to find out where that is first.
The following works for me but you also find other suggestions here.
Add the reference System.Web, and get the current directory by calling:
strFileDestination = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + strFileName;
Remember to give your service write permission in IIS.
If you're running on Windows 2003 and haven't turned on ASP.NET impersonation, and are running the app in the DefaultAppPool or an application pool that is configured to run under the identity of "Network Service", then you'll need to give the "Network Service" account write permission to the destination folder. If you're running the site in an app pool that is using an identity other than "Network Service" then that account may require write permissions to the destination folder.
If you're running windows 2000 then the '<MACHINENAME>\ASPNET' account will need write permissions to the destination folder.
If you've got impersonation turned on then you'll need to give the site's anonymous user account write permissions to the destination folder instead.
To check if impersonation is turned on, open (assuming ASP.NET 2.0) then check your machine.config file (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG) to see if you have the following setting:
<identity impersonate="true"/>
This may also be overridden in your application's web.config.
Additionally if you're running in a partial trust environment then you'll likely only be able to write to the website's application folder because the default FileIOPermission is usually set to $AppDir$, i.e. you can't modify files anywhere else, even with the correct NTFS permissions.
If you're writing to a network share then StingyJack has the answer for you, but the partial trust environment considerations still apply.
But check your NTFS perms first, that's probably the best bet.
Hope this helps
Kev
Stuart, instead of using System.IO.Directory.GetCurrentDirectory(), you may want to use Server.MapPath. You can give Server.MapPath the directory relative to the location of your web service where you want to save the file, otherwise you probably need to pass a full file path "C:\Files\file.txt". As far as the permissions issue, I am usually able to resolve this by adding write access to the folder I'm writing the file to for IIS_WPG and ASPNET users (These usernames may be different on your server).
You should be able to write files from web services. This is most likely a permissions or trust issue. If you are in a limited trust (i.e., Medium trust) ensure that you are writing to a patch in or below your web root. If you are already doing that, or are in a full trust environment check to make sure that the directory has permissions for the IIS worker process to write to it.
Running into a problem where on certain servers we get an error that the directory name is invalid when using Path.GetTempFileName. Further investigation shows that it is trying to write a file to c:\Documents and Setting\computername\aspnet\local settings\temp (found by using Path.GetTempPath). This folder exists so I'm assuming this must be a permissions issue with respect to the asp.net account.
I've been told by some that Path.GetTempFileName should be pointing to C:\Windows\Microsoft.NET\Framework\v2.0.50727\temporaryasp.net files.
I've also been told that this problem may be due to the order in which IIS and .NET where installed on the server. I've done the typical 'aspnet_regiis -i' and checked security on the folders etc. At this point I'm stuck.
Can anyone shed some light on this?
**Update:**Turns out that providing 'IUSR_ComputerName' access to the folder does the trick. Is that the correct procedure? I don't seem to recall doing that in the past, and obviously, want to follow best practices to maintain security. This is, after all, part of a file upload process.
This is probably a combination of impersonation and a mismatch of different authentication methods occurring.
There are many pieces; I'll try to go over them one by one.
Impersonation is a technique to "temporarily" switch the user account under which a thread is running. Essentially, the thread briefly gains the same rights and access -- no more, no less -- as the account that is being impersonated. As soon as the thread is done creating the web page, it "reverts" back to the original account and gets ready for the next call. This technique is used to access resources that only the user logged into your web site has access to. Hold onto the concept for a minute.
Now, by default ASP.NET runs a web site under a local account called ASPNET. Again, by default, only the ASPNET account and members of the Administrators group can write to that folder. Your temporary folder is under that account's purview. This is the second piece of the puzzle.
Impersonation doesn't happen on its own. It needs to be turn on intentionally in your web.config.
<identity impersonate="true" />
If the setting is missing or set to false, your code will execute pure and simply under the ASPNET account mentioned above. Given your error message, I'm positive that you have impersonation=true. There is nothing wrong with that! Impersonation has advantages and disadvantages that go beyond this discussion.
There is one question left: when you use impersonation, which account gets impersonated?
Unless you specify the account in the web.config (full syntax of the identity element here), the account impersonated is the one that the IIS handed over to ASP.NET. And that depends on how the user has authenticated (or not) into the site. That is your third and final piece.
The IUSR_ComputerName account is a low-rights account created by IIS. By default, this account is the account under which a web call runs if the user could not be authenticated. That is, the user comes in as an "anonymous".
In summary, this is what is happening to you:
Your user is trying to access the web site, and IIS could not authenticate the person for some reason. Because Anonymous access is ON, (or you would not see IUSRComputerName accessing the temp folder), IIS allows the user in anyway, but as a generic user. Your ASP.NET code runs and impersonates this generic IUSR___ComputerName "guest" account; only now the code doesn't have access to the things that the ASPNET account had access to, including its own temporary folder.
Granting IUSR_ComputerName WRITE access to the folder makes your symptoms go away.
But that just the symptoms. You need to review why is the person coming as "Anonymous/Guest"?
There are two likely scenarios:
a) You intended to use IIS for authentication, but the authentication settings in IIS for some of your servers are wrong.
In that case, you need to disable Anonymous access on those servers so that the usual authentication mechanisms take place. Note that you might still need to grant to your users access to that temporary folder, or use another folder instead, one to which your users already have access.
I have worked with this scenario many times, and quite frankly it gives you less headaches to forgo the Temp folder; create a dedicated folder in the server, set the proper permissions, and set its location in web.config.
b) You didn't want to authenticate people anyway, or you wanted to use ASP.NET Forms Authentication (which uses IIS's Anonymous access to bypass checks in IIS and lets ASP.NET handle the authentication directly)
This case is a bit more complicated.
You should go to IIS and disable all forms of authentication other than "Anonymous Access". Note that you can't do that in the developer's box, because the debugger needs Integrated Authentication to be enabled. So your debugging box will behave a bit different than the real server; just be aware of that.
Then, you need to decide whether you should turn impersonation OFF, or conversely, to specify the account to impersonate in the web.config. Do the first if your web server doesn't need outside resources (like a database). Do the latter if your web site does need to run under an account that has access to a database (or some other outside resource).
You have two more alternatives to specify the account to impersonate. One, you could go to IIS and change the "anonymous" account to be one with access to the resource instead of the one IIS manages for you. The second alternative is to stash the account and password encrypted in the registry. That step is a bit complicated and also goes beyond the scope of this discussion.
Good luck!
I encountered this error while diagnosing a console app that was writing in temp files. In one of my test iterations I purged all the files/directories in temp for a 'clean-slate' run. I resolved this self inflicted issue by logging out and back in again.
Could be because IIS_WPG does not have access to a temp folder. If you think it is a permission issue, run a Procmon on asp.net worker process and check for AccessDenied errors.
I was having the same problem with one of my ASP.Net applications. I was getting Path.GetTempPath() but it was throwing an exception of:
"Could not write to file "C:\Windows\Temp\somefilename", exception: Access to the path "C:\Windows\Temp\somefilename" is denied."
I tried a few suggestions on this page, but nothing helped.
In the end, I went onto the web server (IIS server) and changed permissions on the server's "C:\Windows\Temp" directory to give the "Everyone" user full read-write permissions.
And then, finally, the exception went away, and my users could download files from the application. Phew!
You can use Path.GetTempPath() to find out which directory to which it's trying to write.