Write permission for folder on a remote server - asp.net

I'm hosting a web site at localhost and need to upload image file to another server named ImageServer with the FileUploadControl.
if (FileUploadControl.HasFile)
{
try
{
string filename = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(#"\\ImageServer\" + filename);
}
catch (Exception ex)
{
throw;
}
}
But i hit this permission error as soon as i try to submit an image.
Exception Details: System.UnauthorizedAccessException: Access to the path '\ImageServer\xxx.jpg' is denied.
ASP.NET is not authorized to access the requested resource. Consider
granting access rights to the resource to the ASP.NET request
identity. ASP.NET has a base process identity (typically
{MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if
the application is not impersonating. If the application is
impersonating via , the identity will be
the anonymous user (typically IUSR_MACHINENAME) or the authenticated
request user. To grant ASP.NET access to a file, right-click the file
in Explorer, choose "Properties" and select the Security tab. Click
"Add" to add the appropriate user or group. Highlight the ASP.NET
account, and check the boxes for the desired access.
I looked into the folder security tab, and Network Service, IUSR, IIS AppPool\Image, and Everyone are granted full control. What else could be missing? I'm not sure what permission should i give to the image folder on ImageServer to let my localhost writing files to them.
P/S: Both server using IIS 7.5
Manually copy files to \\ImageServer\ via windows explorer works though

The main trick is to create a virtual dir which points at \\ImageServer\.
I found an article here. Although is about IIS 6 I think it won't be a problem to work on IIS 7 also.

Related

Configure SignalR with AppCmd.exe on Azure web app

Can you give more details of how you ran AppCmd in Azure web app with SignalR as it requires admin rights? I don't think below will work for this reason.
protected void Application_Start()
try
{
var windowsDir = Environment.GetEnvironmentVariable("windir");
var command = System.IO.Path.Combine(windowsDir, #"System32\inetsrv\appcmd.exe set config / section:system.webserver / serverRuntime / appConcurrentRequestLimit:10000");
Process.Start(command);
}
catch (Exception ex)
{
Trace.WriteLine(ex.GetBaseException().Message);
}
}
Azure web app runs in sandbox. We have no permission to write system drive.
System drive access
Applications can read the system drive as controlled by ACLs on the drive. Applications cannot write to any location on the system drive, as implemented in the sandbox (i.e. even if ACLs allowed writing to a location on system drive, the sandbox would restrict it).
However if you choose Azure cloud service, we can use appcmd.exe in startup task. Of course, it will work like a charm if choose Azure VM as web server.

FileUpload control in aspx.net not allowing file read

I'm trying to read an uploaded file to the server using a FileUpload control, however, I'm gettting the following error:
ASP.NET is not authorized to access the requested resource. Consider
granting access rights to the resource to the ASP.NET request
identity. ASP.NET has a base process identity (typically
{MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if
the application is not impersonating. If the application is
impersonating via <identity impersonate="true"/>, the identity will be
the anonymous user (typically IUSR_MACHINENAME) or the authenticated
request user
I investigated and it seems that the folder do not have the permissions of the Network service account, so I add it but the problem is still there. Here is the code of my FileUpload control:
<asp:FileUpload ID="FileUpload1" runat="server" style="top: 164px; left: 12px; position: absolute; height: 22px; width: 281px" />
And here is the code that I'm using to save the file in my server:
protected void Button1_Click1(object sender, EventArgs e)
{
FileUpload1.SaveAs("C:\\folder\\autoTrack.xlsx");
StatusLabel.Text = FileUpload1.PostedFile.FileName;
if (FileUpload1.PostedFile.FileName != "")
{
this.readFile("C:\\folder\\autoTrack.xlsx"); //this is where the program crash due to lack of permissions!
}
else
{
StatusLabel.Text = "Select a file to start the process!";
}
}
The ACL of the c:\folder folder have the network service with Full control permissions, and inheritance is enabled to propagate to child objects.
Also I read that using a domain account in the Identity tab of the application pool can resolve the problem, but if I change the identity from the predefined Network service to my domain user, I got "Service unavailable" when trying to reach my application.
Any help on this is really appreciated.
First, try giving Everyone permission in the folder to see if it works. If it does, then is just a matter of finding the correct user to grant the right permission. If you are running on IIS you should grant permission to the application pool user as explained here -> http://www.iis.net/learn/manage/configuring-security/application-pool-identities
After a lot of struggle, I was able to find out the issue. You have to set the DCOM properties for the network service in the server. The link below describes how to do it:
http://community.spiceworks.com/education/projects/Setting_The_Default_DCOM_Properties_And_Security
After setting up this I stopped receiving the access errorrs.

How do I configure a upload folder in IIS6 and asp.net? win server 2003 sp2

I have an internal asp.net app that uses the fileupload control to put data files in a "drop" folder. I would like to lock down this folder so only users that are part of a local group can actually authenticate and upload the file.
I have created a group on the server, added the domain users to the local group. I have then given that group write access to the "drop" directory.
When I try to upload a file to the directory I get the expected login screeen but my login doesn't work and after several tries the page errors out with "Access to path '\server\path\fubar\drop folder name\filename.txt" is denied"
How do I set it up so that each user has to login but the login actually works?
TIA
J
You are experiencing a permission issue.
1) You need to set up impersonation on the IIS webserver (http://msdn.microsoft.com/en-us/library/134ec8tc.aspx). This will allow the network credentials to be passed through from any internet explorer browser to the web server.
2) You then need to right click on the upload folder and then go to 'properties' --> 'security' --> 'edit' --> 'add' --> type in the name of the users/groups --> click ok --> select correct privaliges (Read and Modify).
NOTE: if you are operating a an internal web application you dont need the user to log in. Thats the whole point of impersonation. No point in makign people log in if they have authenticated on the network already.
If you must make them log in over the top then you need to validate them against your AD server and then change the user that the page is operting under programatically like this:
protected void Page_Load(object sender, EventArgs e)
{
this.User.Identity = new NetworkCredential("username", "password");
}

Security settings to start a windows service in a ASP.net web app

I have a bit of code in an internal ASP.net application that we use to start automatic services should they be stopped on the server that the web app is running on. The only problem is that it doesn't seem to start the service when its run on the server. It does so fine when its run on my desktop locally though so I'm guessing I have to give certain security settings to the the ASP.net user?
Here's my code:
protected void StartService(object sender, EventArgs e)
{
LinkButton serviceButton = (LinkButton)sender;
string name = serviceButton.ID;
ManagementPath path = new ManagementPath();
path.Server = System.Environment.MachineName;
path.NamespacePath = #"root\CIMV2";
path.RelativePath = "Win32_service.Name='" + name + "'";
ManagementObject service = new ManagementObject(path);
ManagementBaseObject temp = service.InvokeMethod("StartService", null, null);
Thread.Sleep(100);
GetStoppedServices();
}
Anyone have any ideas on how to get this to work?
Edit: For clarification the web app is run on the same server as the server that I want to start services on.
Edit 2: Had a brainwave and tried to use this code instead.. no dice.
ProcessInfo = new ProcessStartInfo("cmd.exe", "/C net start " + name);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
Process.Close();
Rather than using the System.Management objects for controlling services, look into the ServiceController class. All the methods for start/stop/pause are available and in a much more structured manner.
You may still encounter permission issues, though. The executing account for your web app will require permissions to control the target service you wish to affect.
Depending on your platform (which version of Win Serv), different accounts will execute for anonymous requests for your web application. Verify which accounts come into play (or if you have authenticated requests, you know your user) and determine their privileges against your Windows service.
Could be an access rights issue. When you run the application locally (through Visual Studio and the built-in Cassini web server) I think you're running it as yourself, so it makes sense that it would work.
When you run the application through IIS (on the server), its running as whatever user is specified in the application pool. (I think its "Network Service" by default). Check which user it is in IIS and try giving that user permission to start your service.
What version of IIS are you running? If its a Win 2K3 server, I'm guessing 6.0.
Information on configuring the application pool:
IIS 7.0
IIS 6.0
EDIT: You can use SubInACL.exe (a microsoft tool) to configure service permissions:
So let's say you have user "Johnny" and you want Johnny to be able to stop and start the World Wide Web Publishing service. Simply run the following subinacl.exe command:
subinacl /service W3SVC /GRANT=YOURDOMAIN\Johnny=TO
Obviously you will want to replace YOURDOMAIN with the name of your domain. The TO at the end are the identifiers that tell subinacl which actions you actually want grant to Johnny. T is used for "Start Service" and O is for "Stop Service".
For more information, check out Ingmar's blog post about it.
For Windows 7, Windows Server 2008, Windows Server 2008 R2, Windows Vista
Open IIS Manager.(From start->run-> type inetmgr and press enter)
In the Connections pane, expand the server node and click Application Pools.
On the Application Pools page, select the application pool for which you want to specify an identity, and then click Advanced Settings in the Actions pane.
For the Identity property, click the ... button to open the Application Pool Identity dialog box.
If you want to use a built-in account, select the Built-in account option and select an account from the list. Select Local System from the list
If you want to use a custom identity, select the Custom account option and click Set to open the Set Credentials dialog box. Then type the custom account name in the User name text box, type a password in the Password text box, retype the password in the Confirm password text box, and then click OK.
Click OK to dismiss the Application Pool Identity dialog box.
Right click on the application pull and then stop and again click on start

How to find out which account my ASP.NET code is running under?

I am getting an 'Access to the path is denied" error message when running in debug mode. I have tried granting permissions to {MACHINENAME}\ASPNET and to NETWORK SERVICE but this hasn't made any difference. I have also tried < impersonate = true /> using an admin account, this also made no difference. So how do I establish exactly which account is being used?
To find out which NT account your app is running under at any given time, do something like (in VB.NET):
Dim User = System.Security.Principal.WindowsIdentity.GetCurrent.User
Dim UserName = User.Translate(GetType(System.Security.Principal.NTAccount)).Value
When using ASP.NET, this account will match the identity of the application pool, which you configure using IIS Manager. Note that the anonymous IIS user isn't much involved with ASP.NET requests.
C# Code for the vb.net answer
var user = System.Security.Principal.WindowsIdentity.GetCurrent().User;
var userName = user.Translate(typeof (System.Security.Principal.NTAccount));
You could use this code:
C#
Response.Write("Windows Account which runs ASP.NET is: "
+ Environment.Username);
VB.NET
Response.Write("Windows Account which runs ASP.NET is: " _
& Environment.Username)
If you run your application in Visual Studio on your PC (localhost) you'll get your user name. If you deploy ASP.NET web application on IIS, you will probably get the NETWORK SERVICE account, because that is default user running IIS 6.0 (ASPNET on Windows Server 2000's IIS 5.0).
Environment.UserName returns the thread's currently logged-on user. Page.User returns the name that ASP.NET verifies through Authentication and this user in most cases is independent of the Windows logon that is running the current thread. For anonymous requests Page.User is blank, while Environment.User will be NETWORK SERVICE.
As mdb correctly points out in a comment to this answer, Environment.Username will simply return the USERNAME environment variable, which is set on process creation and not updated in case of impersonation and such.
strint t=System.Web.Security.Membership.GetUser().UserName.ToString();

Resources