I have an ASP.NET website on a Windows 2003 Server, that needs to access files from a network share. The network share is password protected and needs a username and password to be provided.
I use forms based authentication on the website and not windows based.
So my problem is, when I try to read any file from the networkshare using the code below, it throws access denied
DirectoryInfo networkShare = new DirectoryInfo("\\TestServer\Share");
So I tried using Impersonate by providing the username and password of the network share to the impersonate function call, however the call obviously fails since that username does not exists on the ASP.NET webserver. So then I passed the username and password of a login that does exist on the webserver, so this time the impersonate call works however it still can not access the network share 'cuz the network share username and password are different.
So finally, I created the exact same username/password on the webserver which matches the network share. This time impersonate function call works and so does network share. I'm able to successfully read from the share.
So my question is, is there a way I can read the network share without adding the username in the webserver. 'Cuz everytime the network share login changes, I'll have to again make a new username in the webserver too. Which is not ideal.
Any ideas?
The "right" way to do this is to run the webserver's AppPool as the identity that can access the share. That way, the only credential storage is done securely in the IIS config (rather than in your code or in readable config files). Putting the webserver and fileserver in the same Windows domain (or different domains with trust) is the easiest way, but the "same username/password" thing should work there as well.
If you don't care about putting usernames/passwords in your code or config, you can P/Invoke to WNetAddConnection2 and pass the username/password- then you should be able to access the share. This doesn't require the webserver to have a matching account, but you really should secure the password (look into System.Security.Cryptography.ProtectedData for encrypted registry storage).
Related
I am trying to create an authentication system that works within the limitations of my organisation's network infrastructure both when inside the local network and outside.
When inside the local network I want people to be able to access this ASP.NET Web Forms application without having to log in using their Windows login.
Externally I want people to have to log in through a custom login form.
The reason is that Windows authentication does not work outside of our local network, due to the local infrastructure.
So, I created a password protected folder by disabling anonymous authentication just for that folder, and then on every page request I check if the user is flagged as being logged in (details on how I do this are unimportant) and if they aren't I redirect to a page that does an AJAX request to a web service located inside the password protected folder to see if they are logged in on the local network. If they aren't then it redirects to the custom login form page.
Now this all sounded like a good idea at the time but in practice it does something undesirable... When an external user attempts to access and the AJAX request is made, I get a browser username and password prompt which has to be cancelled to continue.
I appreciate that this type of authentication is part of HTTP and probably can't be bypassed, even using AJAX, but any ideas how I can get this working without the username/password prompt or an alternate way of checking whether local network or external access?
I know I could check the IP address but I understand this can be faked (although that would only cause an issue to the user attempting to do this).
I also know I could have a different entry point for internal or external but I wanted to avoid this.
I couldn't find a solution for exactly what I wanted to do, so I opted to check if the user was on the local network by checking their IP address.
Although this is sent via a HTTP header and can be faked, it will only result in the user being prompted for username and password via Windows authentication.
We have 2 servers in DMZ. First one is application server, let's call it APP machine. The other is a file server, let's call it FILE. Web site running on APP machine under IIS is trying to create a file in a shared directory located at FILE server.
When application pool is running with some user in IUSR_IUSRS or NETWORK SERVICE writing to remote location fails. I cant authorize this user in shared folder, because that FILE machine can only see local users.
I created a user X on APP machine (APP/X) and another one with the same username on FILE (FILE/X). Then I added FILE/X user to credential manager on APP machine. When APP/X and FILE/X users have different passwords writing fails again. But when passwords are the same then writing just works.
I cant understand why passwords matter. At the end of the day they are two different users APP/X and FILE/X. Could someone clarify this phenomenon?
When the local user account on APP attempts to connect to the FILE server it passes it's credentials (username and password). If that combination isn't an exact match against a user on the FILE machine then it will fail.
There are multiple ways to do this "correctly". The most common would be to have a domain setup in which the site on the APP server runs under. That way you could just authorize the user to have rights on the FILE server.
If you can't have a domain controller, then the username and passwords must be kept in sync on the two machines.
What is the risk of not using a trusted connection?
For example here is a scenario: I have created a very simple application which only has 4-5 lines of codes which uses an SQL connection with my connection string within web.config, and sends a select command to my database, and display results in an interface.
What are the security weakness here?
Edit:
I know trusted connection is related to authentication, what I wonder is I don't know how can the system be hacked if I don't use it ? (I will use my application at my company's servers and the application is a public application, so every company member can use it, so why do I need a trusted connection if it is a local company application ?)
To look at it the other way around, the main benefit of trusted connections is that you do not have to manage passwords in your application. If your application needs a password to connect to SQL Server, then where do you put the password (or connection string) so that the application user (or other developers, or sysadmins, or external consultants, etc.) cannot read it but you can still change it easily when required?
Passwords in files or the registry can often be read by users because when they run the application it has to retrieve the password, therefore the user needs access. Or a sysadmin or consultant has access to the filesystem where an application config file is. Obfuscating the password with some form of encryption is possible, but then you have to secure and manage the decryption key. Hard-coding the password in the application makes it difficult to change and also makes it highly likely that the password will be visible in the source control system, which is typically a relatively insecure system (in practice, if not by design). You can create a web service that the application gets the password from on startup but then you have to authenticate access to the service somehow.
Using trusted authentication avoids all of this completely by making the operating system responsible for authentication and unless you are a world-class security programmer, the odds are good that Windows provides a more reliable mechanism than you can create yourself.
I will use my application at my company's servers and the application
is a public application, so every company member can use it, so why do
I need a trusted connection if it is a local company application ?
Security risks in non trusted connection lies how you store SQL server passwords and use them in application. if you store passwords in config file or hard code in program, any other developer who has access on your code can view it and on the worst can change database in such a way that may break application or steal sensitive information. it will be a privacy breach as well and your company may be sued for this ( you can't just imagine what can happen).
#Pondlife has also elaborated very well.
AFAIK, the only extra layer of security a trusted connection gives is authentication. If you use a trusted connection then Windows will authenticate your connection in Active Directory.
A quick google yields this link:
What is a Trusted Connection?
My feeling says it's not posible but anyway I am curious if there is at least a workaround for accomplish this.
Basically I am working at my client site and my machine is not connected to the domain.
What I want to do is running a web application locally under a domain account, and using the webdev server.
The webapp uses the default authentication, windows authentication that is.
I tried using impersonation with domain\user & password but I got the following error
Could not create Windows user token from the credentials specified in the config file. Error from the operating system 'Logon failure: unknown user name or bad password.
I have to mention that the username and the password are correct.
Thanks in advance
Iulian
If you cannot access the domain controller (or your computer does not know what domain controller to use), there is no way finding out if the password is correct or not. What normally Windows does, is asking the DC "does this password match this account" (simply speaking). Now in your scenario, there is no DC. Hence, "unknown username".
My ASP.NET MVC 2 application runs under built-in local NETWORK SERVICE account. I want to set up access permissions for the folder which resides in another computer, but in the same domain. I located that folder right-clicked to open its properties form, clicked to Security tab and pressed Add button which displayed Add user form with correct domain name in the location field. I referred to the account with following syntax:
<domain name>\<server name>$
because I learned that NETWORK SERVICE account uses machine account when connected to other computers in the domain.
However, the system couldn't find the account, so refuses to add the account. Without the domain name it adds a user, but that user seems to be local user, not web server's NETWORK SERVICE account. What am I doing wrong?
By the way, the above syntax worked when I created login for the sql server which is different computer from the web server.
OK, I will answer my own question. The above syntax \$ was correct. Just make sure to select computers checkbox in the object type, when adding user permissions.
I have been in this same situation before. I don't think I got it to work with the Server/Network Service but this might be worth a try.
Figure out the account network service is using to access the network resource.
Configure windows auditing (on the server the folder is located) to log the failed security events of the folder.
or monitor the folder with something like filemon.exe
.. from here you can try and add the account to the security settings of the forlder. (IIRC I did'nt ever get this to work)
Alternatively you can ensure the action is performed under the context of a domain user. Either by:
Impersonating the user in code and performing the action (my preference)
Setting the impersonation settings in web.config to a named user
setting the application pool to run as a domain user.