I have an ASP.NET 2.0 [no ajax...yet] web site that will be deployed in compiled form on multiple customer sites. Typically the site will be intranet only. Some customers trust all of their people and don't care about limiting access to the site and/or page functions, others trust no one and want only certain people and/or groups to be able to view certain pages, click certain buttons, et al.
i could do some home-grown solution, possibly drive the access permissions from a database table, but before i go down that road i thought i'd ask in SO: what is a good solution for this situation? preferably one that can be controlled completedly in the web.config file and/or database, since rebuilding the web site is not possible (for the client, and i don't want to have to do it for them over and over). Active Directory integration would be a bonus, but not a requirement (unless that's just easier).
as a starting point, i'm thinking that each page/function point in the site be given an identity and associated with a permission group...
EDIT: web.config authorization section to allow/deny access by role and user is good, but that is only half of the problem - the other half is controlling access to the individual methods (buttons, whatever) on each page. For example, some users can view whatchamacallits while others are allowed to edit, create, delete, or disable/enable them. All of these buttons/links/actions are on the view page...
[ideally i would make the disabled buttons invisible, but that is not important here]
EDIT: some good suggestions so far, but no complete solution yet - still leaning towards a database-driven solution...
- security permission demand attributes will throw exceptions when buttons are clicked, which is not a friendly thing to do; i'd much rather hide buttons that the user is not allowed to use
- the LoginView control is also interesting, but would require replicating most of the page content several times (once for each role) and may not handle the case where a user is in more than one role - i cannot assume that the roles are hierarchical since they will be defined by the customer
EDIT: platform is Win2K/XP, Sql Server 2005, ASP.NET 2.0, not using AJAX
It sounds like you could use the LoginView control, which can show panels of controls to only certain users or roles. Roles are most flexible- if no security is required, put all users in all roles.
Use in combination with standard web.config security (integrated windows with active directory, or forms authentication (the asp 2 Sql server schema or your own).
i think i'm going to have to combine AD authorization with 'features and permissions' tables in the database in order to get the fine-grained control that we need -
examples:
The final solution reduced the notion of 'feature' to a binary can-use or cannot-use decision, and added a 'permissive/not-permissive' flag to each feature. This allows features that most everyone can use to be defined as 'permissive', and then the permissions table only has to record the groups that are denied permission to use that feature. For a feature defined as not-permissive, by default no one can use the feature and you have to create permission table entries for the groups that are allowed to use the feature. This seems to give a best-of-both-worlds solution in that it reduces the number of permission records required for each feature.
While I've never used this before in practice and cannot argue its merits, I know that .NET has role based code security which allows you to declaratively lock methods down by role or user. For example:
Role based security is covered in more detail here. I don't know that it will help you much though considering it will require a recompile to change it; however slapping labels on methods is faster than building logic to show/hide buttons or do security validation in code.
Additionally, you'll want to read up on Integrated Windows authentication to gain the Active Directory possibility.
I think what you need to do here is implement a set of permissions query methods in either your business objects or your controller. Examples: CanRead(), CanEdit(), CanDelete()
When the page renders, it needs to query the business object and determine the users authorized capabilities and enable or disable functionality based on this information. The business object can, in turn, use Roles or additional database queries to determine the active user's permissions.
I can't think of a way to declaratively define these permissions centrally. They need to be distributed into the implementation of the functions. If you want do improve the design, however, you could use dependency injection to insert authorizers into your business objects and thus keep the implementations separate.
There's some code that uses this model in Rocky Lhotka's book. The new version isn't in Google yet.
I prefer to grant access rights to AD groups rather than specific users. I find it's much more flexible.
I don't know much about your application, but you might want to look at the authorization tag in the web.config file:
You can separate web.config files each directory within your web application, and you can nest directories. Each web.config file can have it's own authorization section. If you put different pages in each directory you can effectively tightly manage security by allowing a specific role in each web.config, and denying everything else. Then you can manage members of each role in active directory. I've found this to be an affective solution because it makes good use of Microsoft's Active Directory and ASP.NET security framework without writing your own custom stuff, and if you use roles, it's possible to offload the management of role membership to someone who doesn't ever have to touch the web.config file they just need to know how to use the AD management console.