I am quite confused about this and none of the texts / docs / SO questions have elucidated the matter for me.
I want my asp.net MVC app to be able to save an XML doc to a folder on the server. But I am getting an exception...
Access to the path 'D:\blah\blah\folder\xml_data.xml' is denied.
So as I understand it my application is running under a user account that does not have write permissions.
I think I had this problem before and my solution was to contact my web host and ask them to give my site permissions.
But what if I want to create my own custom set of roles with corressponding permissions? Do these have to be added into IIS? Would I have to create a list and then hand it over the the web host? What would such a list look like? As I understand it, it is not possible to configure roles and permissions in web.config, is that correct?
Once I have the roles and their permissions set up how to I set the default role for the app to run under and also how do I programitically change the role that the app is running under?
ps. I don't want to use asp.net membership I would like to know how to set this up myself.
Use asp.net membership. I don't care if you don't like it. Use it. It's easy, it's simple, and it gets security right. You will mess security up if you do it yourself and don't know what you're doing.
People give membership a bad rap, it's a good tool. Most people just make the wrong assumptions about it.
You define your roles in the membership/role API. This is stored in your database. You can't have roles without a user to apply them to, so you need a membership system of some type.
EDIT:
There are two kinds of users here. The first is the user that the ASP.NET worker process runs as under IIS. This is the user that your host must define, and allow to access various folders to access files.
The second is the IIdentity user of asp.net, this is the user that asp.net defines for the logged in web user, and this is completely seperate from the Worker process user. IIdentity users have no inherent operating system rights or privileges, other than those assigned to the worker process identity.
In other words, IIDentity based users run as the same Worker process identity in IIS.
The exception to this is when you define "impersonate=true" in the web.config, and this allows the worker process to "log on" to the OS as the user in question. In other words, the worker process will run as the web users credentials. This requires that the web user have credentials in the OS as well.
The other exception is that you can specify a specific OS user to impersonate in the web.config. But, again, there must be an operating system user to impersonate. Also, impersonation is a very expensive operation and takes a lot of system resources.
See http://msdn.microsoft.com/en-us/library/aa292118(v=vs.71).aspx
Related
I am creating a project which has a login portal with multiple applications and websites. I want to allow the user to login and then click any application and have access to it. Some considerations are: each application is defined in a user profile, ie which users can see what. also each application privileges are different for each user. so user a may be an administrator of application a but just a normal users in application b.
What i know.
I can have one auth cookie created in the main portal which with setting the machine key and same authcookie name, each application can use it. I have done a test with this and it seems to work.
My problem
As each site/ virtual directory has different privileges per user and per application when the user access a site i need to get his privileges from the databases but I cant then overwrite the auth cookie userdata with the new details because he may have multiple tabs etc open at a time on different sites. So how can i have an extra cookie store per user and per application for holding application specific details. I know I could go to the database each time but that's allot of overhead for each post back.
Maybe another option is to use the main authcooke for checking the user is logged in then have a new auth cookie per aplication and user, but how can i have 2 authcookies, that may get confusing and the second needs to timeout when the main one does et c i think
Any help suggestions would be gratefully appreciated
THanks
------------------- EDIT -----------------------------
we have one user table for all all sites not 1 per each site. then we map the user to an application and then the user application and role. so when you get to an application it has to check if the user has access and what there role is. all other user details are already in the auth cookie when loggedinto the main site. We do it this way because we have to manage users in one application not each application. Hope this helps understand my requirements.
What you are describing is a 'classic' SSO (single sign-on) example. There are lots of ways people have tried this and they are well documented on Google.
One way to do this is to have your SSO server (e.g. the first place you land and log in) to issue a security 'token' (e.g. a Guid) and then either store this in a cookie or append to URLs. Each subsequent call to an application can look-up the token in a database, verify it's validity and carry on (or boot the user out if invalid).
Using a database also allows you to set a timeout for all applications for which the token is valid.
This can then be extended to allow the database to store which apps each user can access etc. I've described this in very broad terms but it may be a good starting point.
Hope this helps
BTW: querying the database on each request isn't too much of an overhead. I have applications that do just that and are still performant when loaded with 300+ users.
The following webpage talks about using impersonation in code (ASP.NET): http://support.microsoft.com/kb/306158. I am thinking about creating a class for the code, then the application can call impersonateValidUser and undoimpersonation.
I am concerned about putting usernames and passwords in my code as surely anyone will be able to see them using a tool like ILDASM. What is the best way to hide these passwords?
The article has a section titled: Impersonate the IIS Authenticated Account or User. I thought about creating an impersonated user in the Web.Config, but this would mean that the entire application is run as the inpersonated user. I only want a very small part of the application to run as the impersonated user - when it is necesary to access and update active directory.
I really like your intention to have have only the part of the application that does the AD updates running under a highly privileged account. I also share your concerns about storing the password in the web.config or in the code.
I can think of two options for you.
Store the account details in the web.config and encrypt that part of the web.config. That will ensure that only an administrator of the web server can get hold of the password. Someone else getting hold of the web.config won't understand a thing of the password.
Create a small, separate WCF service with the AD update code. Then run that WCF service in a separate application pool, with the app pool set to the identity of the user that has access to the active directory. Setup a restricted, localhost-only endpoint for the WCF. The WCF service should have access control to only allow access from a dedicated account. That account should be set as the identity of the app pool of the main web site.
Option 1 is easier to implement and protects the password rather well. Option 2 offers better protection for the passwords as they are not stored in the web.config at all - they are part of the IIS configuration. Option 2 also adds complete isolation between the privileged code and the rest of the system as it runs the AD update code in a separate process. With that isolation, it is much easier to make a code review for the AD code to check for security issues.
Big picture: I have been asked to create a search engine for our company's intranet. Such a search engine will crawl pages supplied to it by XML files for each independent application on the intranet. Problem is, the entire intranet is using Forms Authentication, and so the crawler will have to have access to each application without actually having user credentials (e.g. username and password).
Each application within the intranet has its access controlled by a permission manager, which is essentially a wrapper on the default Role Manager ASP.NET comes with. Each application can define its own roles and assign people who have those roles.
Please note that there are potentially hundreds of applications.
The crawler has access to the permission manager's database, so it knows what all the roles are. Therefore my idea was to have the crawler create a cookie that identifies it as having all roles for each application.
The problem I'm running into is this: how do I create a forms authentication cookie which already has the roles assigned in it without creating a corresponding user (IPrincipal).
It is entirely possible that I've failed to completely understand how Forms Authentication works, and if so, please tell me what I can do differently.
This is probably not what you want to hear, but...
I would just have the crawler authenticate like anyone else.
Given that this is a crawler you control, why fight Forms Authentication? Seems logical to create a user with all required roles in each application (hopefully you have a central administration point for the hundreds of apps, else I would not want to be an administrator there ;-)
If you do anything that allows "just the crawler" special access (bypass user-based authentication based on... what? The crawler's user agent? A specific origin IP?), you create a security hole that a hacker can leverage to gain access to all of the intranet applications that have otherwise been diligently secured with user IDs, passwords and roles (in fact, the security hole is particularly wide because you propose granting access to EVERY role in the system).
It sounds like what you want is an appropriately encrypted System.Web.Security.FormsAuthenticationTicket (which then gets attached to HTTP requests as a cookie).
The encryption logic is located in System.Web.Security.FormsAuthentication.Encrypt(), which I think uses the MachineKey as the encryption key. Also have a look at the GetAuthCookie() logic (using Reflector).
You might have to write your own version of the encryption method, but what you want to do should be possible, provided you have a copy of the remote site's encryption keys. You don't need the user's passwords -- only the user name is encoded into the Ticket.
It seems to me that the problem is not yet well defined, (at least to me!).
Why do you need to crawl the pages and index them if there are fine grained permissions on them?! How do you show search results without violating the permissions? Why not index the back end by passing the pages altogether (I mean index the database records not the pages)....
I'm working on an web application using ASP.NET 4.0, C#, and IIS7. The web application is a content management system that defines multiple user roles, such as editor and administrator. These users and roles are managed by the asp.net membership framework, and the associated database tables are integrated into the web app's database using aspnet_regsql. Finally, the web app is running under the ApplicationPoolIdentity. Thus, the web app runs under the virtual account "IIS AppPool\" which it does not share with any other application.
The site is designed such that user accounts are handed out by the administrator (there is no public sign-up page), although this detail may be irrelevant. In any case, the administrator should have the power to create and delete users and edit any of the content on the site. Editors, on the other hand, should be capable of editing only assigned sections of the site. Finally, anonymous visitors to the site should only be capable of viewing the content, with no option to edit.
The question is: Would it be insecure to just give read and write access in the SQL Server database to the IIS AppPool\ virtual account and give functionality to different user roles in the underlying business logic for the web application?
I wouldn't think so, but due to the necessity of the integrity of the data, I thought it might be a good idea to seek the opinion of another developer.
If (and only if) this does pose an unforeseen security risk, would it be a better idea to use impersonation, store multiple connection strings in the web.config file with SQL authentication, or track user privileges in the database itself?
The question is: Would it be insecure
to just give read and write access in
the MSSQL database to the IIS AppPool\
virtual account and give functionality
to different user roles in the
underlying business logic for the web
application?
This is how it's usually done, and for most business cases this is enough. There are insecurities in every application so you have to do the best you can to avoid buffer overflows, script injections and SQL injections, scrub your input, etc.
If (and only if) this does pose an
unforeseen security risk, would it be
a better idea to use impersonation,
store multiple connection strings in
the web.config file with SQL
authentication, or track user
privileges in the database itself?
Using impersonation is not uncommon, and very easy if you're using Windows Authentication. It's an administration headache, since users have to be added via database security in addition to the application database. Multiple connection strings is probably the least extensible and favorable of the approaches, not to mention it would hurt performance on a busy site.
I have a normal Windows Server 2008 installation with II7. Each website has it's own application pool. But there is a security realated problem.
There is no restriction for an asp.net application to write a file into C: or any other directorys.
In IIS 6 before this could happen I would have to set those rights in the windows folder secuity permissions and allow the ASPNET_Usr to do that.
What is the best practice for hosting asp.net applications and not allowing them to write an read files in eg c:?
EDIT
Anonymous Auth. is enabled and the User specified is "ISUR". All other Authentications are disabled. In the application pool I use as Process Identity "Network Service".
I created a new User on the Server (not in the domain) "www.xyz.test" and deleted all his group memberships. Changed the Process identity to this user and made the anonymous authetication use the app pool identity and was still able to write to C:.
Changing the trust level is in my case not an option because we use an 3rd party application
It all depends on what user account your asp.net website is running on. I.e. is it Network Service? As far as I am aware, if I want to be able to write to the web directory then I give my website account write access solely to the directory where I want to save files. The account I use is the one used for Anonymous Authentication.
I.e. I have a website called mycompany.com . I create this user account as part of the domain user group. I add this as the anonymous authentication credentials and give it access to the web root, and also write access tot he nested folder which I want to write too.
The User account would be called mycompany.com so i know that it has a reponsibility solely for permissions related to the web and that particular website.
Sounds like the web site permissions (in IIS) are set to either
- Windows Auth: And you are logging in with someone who has permissions to those folders
or
- Anonymous Auth: And the account that is being used for impersonation has permissions
Best practice would be to make sure the account which is being used to access the site (i.e. if windows auth - your account or if anonymous then the account which is impersonated) does not have permissions on the folders.
You could also raise the trust level to medium, high or full in the machine.config for additional security enforcement policies - however use with caution as it can cause some ASP.NET apps to fail.