Edit 6:
Using Windows Integrated authentication (with an account that has access to the share and the database), I can get the list of files/directories. However, refresh the page and get an UnauthorizedAccessException
. Perhaps a NetBIOS or ActiveDirectory limitation.
5 months and still no solution, other than 'use impersonation' (via P/Invoke it seems, since the built in .NET way seems so flaky), but that will also have the same problem. Hard coding username/password is not an option.
Development (Windows 7) box (using IIS or Visual Studio's) built in web server) works fine..
Edit 5:
From what I have read on the internet and in this question, the only ways for this to work are:
- Basic Authentication
- Impersonation
- Have files on same server as Web Application
None of these are an option as either
- Users have to login each time - downside: extra barrier to entry, should be a seamless experience
- User name and password hard coded - downside: passwords change, the user coded (asp.net account) in won't have access to the files
- Too many files to store on the web server, not enough disk space
Since there must be Windows Forms applications that can access UNC shared files, I would have thought this would work. That, and the fact when remotely connecting to the web server and using Windows Explorer I can access the files.
Maybe ASP.NET/IIS security prevents it from ever working without impersonation via P/Invoke. Or maybe being blocked by a firewall?
Edit 4:
One thing that does work is using Basic Authentication - Integrated Windows Authentication and Digest Authentication do not. However, that is not really an option as the password is sent in clear text and the user would get a prompt when they visit the page (not something I want to do).
Edit 3:
No matter what I try, I can not get a list of files or directories on a UNC path (both a combination of these and individually turned on)
- Given 'Everyone' full access to the folder (not just read)
- Given the ASP.NET account 'Act as part of the operating system'
- Given IIS_WPG group 'Act as part of the operating system'
- Used
<authentication mode="Windows" />
- Used
<identity impersonate="true"/>
If I remotely connect (using RDP) to the server with the same account as I use to log into the site, I can access the files fine. It just doesn't work through code.
Edit 2:
What I have tried is:
- Turn on Windows Authentication: files can only be accessed when on same machine (not UNC share), cannot connect to database
- Turn on Forms Authentication, can connect to database but not access files (due to
InvalidCastException
as Identity is now aGenericIdentity
)
I can't use Windows Authentication, as I have no way to add roles. I don't want to prompt for a username / password as that is an extra step and it is not over a secure connection (i.e. SSL). Also I can't give the ASP.NET account access to the files (since I am not a domain administrator).
Edit:
The path is a UNC path, not on the local PC.
Using forms authentication, when I try to cast the current user identity to a WindowsIdentity
in Visual Studio and debugging I get an InvalidCastException
. I simply have:
WindowsIdentity id = (WindowsIdentity)HttpContext.Current.User.Identity;
Then the error I get is:
Unable to cast object of type 'System.Security.Principal.GenericIdentity' to type 'System.Security.Principal.WindowsIdentity'
I am using impersonation to get a list of files, since the ASP.NET account does not have access to these files. It works when using IIS, but not in Visual Studio:
WindowsIdentity id = (WindowsIdentity)User.Identity;
using (System.Security.Principal.WindowsImpersonationContext context = id.Impersonate())
{
files = Directory.GetFiles("\\server\share");
context.Undo();
}
Adding <identity impersonate="true" />
to the web.config
does not do anything - although I don't want to do that as I am using the ASP.NET account to query a database, which the user does not have access rights to (resulting in Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'
).
When I turn on Windows authentication through the web.config I then get UnauthorizedAccessException
when trying to get the list of files from a remote share (which I could otherwise access if I remotely connected onto the IIS box as the same user on the client PC).
In addition, the ASP.NET account is an account set up in Active Directory, not local to IIS.