Is ASP.NET role based security a true role based access control system? - asp.net

From what i have read from this paper
I understand that a role based access control system is one where users can be assigned to roles where roles specify permissions to perform operations on objects
But in asp.net we do not specify "Operations on objects", what i mean here is that how can we specify "All users in Role R can perform a delete on object O"
Where is the Object Part in ASP.Net

The security model is asp.net is pretty limited. In essence you only have control at the Role level. Which means that for any operation you have to test to see if the user is any of the roles that you want to allow that operation to be performed.
We took the path of defining our own model that gives much more granularity. Basically we define operations and assign those operations to various roles. This way we can test if they have a "delete account" right versus testing if they are in "Admin", "Account Admin", or any number of other roles. It's very similar to how Active Directory works. Further it allows us to reconfigure roles as needed.
There is a piece called Authorization Manager (AzMan) that ships with windows. It can work with your membership provider to provide operation level control. Some people have had success with it, but others have complained that it's difficult to get working. We used it about 5 years ago on a project and at that time it worked about 95% of the time. The other 5% it had communications issues with our AD controller.
Which leads us to your question: Is the built in ASP.Net membership provider a true role based access control system? No. It allows you to define Roles, not operations.

Check out rhino security if you need something more fine grained.

As suggested in previous posting, to achieve more granularity you would need to build up on the existing ASP.net membership and role providers. There are third party controls such as http://www.visualaccesscontrol.com that provide role based Module Access Security and Data Access Security as well. With Visual Access Controls you can add administrative functionalities to your ASP.net web application to dynamically restrict the users to the activities they are allowed to perform and the subset of data they are allowed to see based on their respective roles.

You are implementing the delete operation, so it is up to you to check if the logged in user has permission to delete the object. For example, you might create a role "CanDeleteOs". Then, your code would look like this:
if ( !Roles.IsUserInRole("CanDeleteOs") )
throw new Exception("User does not have permission to delete O's.");

Related

ASP.NET MVC Authorization: Permissions in Place of Roles

I know this is a question that has been asked over and over but I'm attempting to implement permission based rather than role based authorization in an ASP.NET MVC application. So instead of just having high level roles like Manager, Admin, or User, I need to have permissions like ViewTask, AddTask, DeleteTask. I have read a ton of comments on this and it seems like the easiest solution is to just treat roles as permissions and define "roles" of ViewTask, AddTask, and DeleteTask.
Is such an approach really a good idea? Some of my concerns are that you could end up with over 100 roles depending on the size of the application which would then rule out the ability to do role caching in cookies and thus every call to User.IsInRole hits the database. If every action method is going to be decorated with [Authorize(Roles="XXXX")] am I going to see serious performance issues?
My other issue is that I still want to keep the concept of a role around so that an administrator can simply associate a user with a role that has a predefined set of permissions. Using the approach above my thought was to create a separate entity in my application named Group and that Group would be responsible for keeping track of the ASP.NET roles that are assigned to that Group. So, when a user is associated with a Group, I can retrieve the ASP.NET roles that need to be assigned to the user and add all the roles.
Has anyone implemented a system in such a way? Any opinions or thoughts on this approach would be appreciated.
Thanks
I agree with #jlew about caching the user's data and when the cache expires - just reload it. There's no use trying to force this data to stay persistent. Additionally, if you want to move away from the ASP.net role providers, you could roll your own security as I've described in this reply. This has the advantage of allowing very custom security solutions for roles/individual permissions.
The following is just an idea that I've been toying around with lately (just some food for thought). Why not use the RESTful urls of MVC to define "permissions". For example:
/tasks/add could define the permission for adding tasks. These could somehow be hierarchical so that giving a user permissions on /tasks/add also gives them permissions on /tasks. Then, you could use a global action filter that would build the URL given the route values. This would also allow really interesting approach for individual item security configurable via runtime. For example, /tasks/edit/23 could somehow grant edit permissions on task with id 23. Anyway, this might not even be helpful at at all... but it's just thought I thought you'd like to maybe consider.
Cheers!
We solve the problem by caching the principal on the server side, so that the "permission roles" do not need to be in the cookie and we do not have to re-load on every request. You can actually get around the cookie size limitation by chunking your cookie data into multiple cookies (Windows Identity Framework does this.) But, you may have bandwidth or other concerns with big cookies.

ASP.NET Custom Role Provider - Additional Fields

I am faced with a security model problem when migrating my code to ASP.NET.
In the application:
There are multiple roles. (Role A, Role B etc)
There are multiple input/output fields. (Field A, Field B etc)
There are multiple permission levels controlling access to each field. (Read, Direct Edit, Edit With Approval, None)
Each role has its own permissions to fields. (Role A has Read Permission to Field A; Role B has Direct Edit permission to Field A etc)
Every role can be assigned to users and they are assigned by Geographic information. (User A is assigned to Role A for Continent: Europe - Country: Germany; User B is assigned to Role A for Continent: Europe - Country: France; User A is assigned to Role B for Continent: Europe - Country: France etc)
Users can have multiple roles
User identity is coming from Windows Authentication.
So my question/problem is: is it possible to represent this type of kind of multi-layered security model using ASP.NET internal membership/role providers?
If so, what should my starting point be? Creating only custom role provider with custom methods and fields be enough?
Even with the built in features of ASP.NET, the Membership Provider, and user controls, you will still have to write and manage the custom behaviors and interactions.
As example, the Membership Provider has easy ways for your to create roles and check for the existence of roles. But you will have to create the business specific dashboard call the features of the API that are appropriate to expose for your application. As example, at many of the organization that I have worked with role creation was a database only activity. User controls or site behaviors based on role were a code only activity. Managing which roles were assigned to users was a feature exposed via an admin page in the application. If a need for a new role was identified, it had to be first created by a DBA, then code/controls that were responsive to that role had to be written. After these items were deployed, application administrators could assign or remove roles to users.
To address you comment to your question, if you have Europe_Germany_RoleA, the Membership API provides methods for you to create that role, map it to a user, and to check for its existence on a particular user. like...
if(User.Roles.Contains("Europe_Germany_RoleA")) {
//your code here
}
but you would need to map that particular role to information or features specific to your application.
In retrospect, maybe what you really want to look at is the Profile Provider. Still part of the Membership set (Membership, Roles, Profiles), it is more designed to carry information. You could customize the Profile object to meet the needs of your application. For example, if you looked at this as Sectors (for lack of a better term) that could be loaded when the user logged in, you could do queries like...
if(Profile.Sectors.FirstOrDefault(sd=> sd.Name == "Europe_Germany_RoleA") != null) {
//bind to a grid, show a control, do something significant
}
and that might fit your problem better. Roles are truly only meant to act as flags (Does he have this role or not, then do something or dont), but the Profile object is designed to be customized to carry pertinent data for a user.
You can always extend it. The ASP.NET Membership model uses GUIDs as IDs for users and roles. You can add new tables that represent the added functionality and have them reference the original Membership tables.
Your problem is not in the role provider, or the membership system. This system is suitably flexible enough for your needs, and allows you to assign multiple roles to individual users. You can either use a SQL table to store these roles, or you can use Active Directory, AD is probably easier to manage the users with.
Your primary problem is going to be how you assign permissions to the fields and other objects. This means you can't just use standard drag and drop web forms, but will have to build your fields dynamically.
It's easy enough to check whether a user is in a role, this is a one-line call. But, your roles will likely not be hard coded, so you need a way to store fields and the roles associated with them, and a way to build the fields based on the users privileges.
EDIT:
Another option is to build the forms as if there was no security, then in your pre-render event go through and apply your security to each field, disabling and/or hiding fields you don't want the users to see. This may require relaying out the fields if you choose to hide them.

Data-based authorization in ASP.NET

Summary: I need to authorize pages based upon the data present in the query string of a url, not just the page name.
Background:
Let's say I'm building a library inventory system. Users can be created and assigned to a single library in either an Admin or User role. There are hundreds of competing libraries in the same database, so it's important to ensure that users of one library cannot view inventory from another library.
Right now I'm using a pretty standard ASP.NET setup: Forms Authentication using the SqlMembershipProvider. Authorization using the SqlRoleProvider, configured via <authorization> sections in the web.config. Security trimming with the SiteMap provider to hide unauthorized pages.
To control the inventory information from leaking, I'm manually checking a user's associate library ID with every inventory query. It works, but it's tedious and prone to errors. There has to be a better way.
Question:
Now users have the ability to create arbitrary "collections" within a library. (e.g. Collection A has Books 1, 2, & 3 in it.) Admins want the ability to grant Admin / User access on individual collections, not just the entire library.
So, if a user goes to www.com/Book.aspx?BookId=1, the system needs to ensure that user has permissions for the collection that "Book 1" is in before showing the page. If they go to www.com/Reviews.aspx?ReviewId=23, I need to make sure the Review is for a book that is in a collection that they have permission to view.
1) How can I implement this in the most standard ASP.NET way possible?
Manual checking within a base page?
A custom HttpModule?
A custom Role Provider?
I'm not interested in how to store the admin/user permissions, but rather how/where to authorize based on those permissions.
(examples on how to implement any of those are appreciated)
2) To further complicate it, I'd still like security trimming to check if the user has Admin rights on any collection or library and hide the admin pages if he doesn't.
I wouldn't handle this anywhere near the UI (ASP.NET) layer but rather within the application services. Something like:
Build services which take an IPrincipal (or your custom user object)
as a constructor parameter.
When requesting a book/review/whatever, the service is responsible
for looking to checking to see if the user has access to the
resource.
If the user doesn't have access, do some predetermined thing (pass a
message, throw an exception, return null).
This will be alot more testable and usable in the long run then worrying about it from the ASP.NET UI side.
If you have to handle it on the ASP.NET side, I'd consider using a custom IPrincipal and custom RoleProvider to wrap up each library as a role to access, then you could use most of the LoginView, etc. controls.
Normally, this sort of thing is handled at the data level. It has little to do with ASP.NET, other than ultimate you need a user-id (which comes from Membership). What you do is find some part of your entity that you want to control access on, then you create all your queries to filter on that.
For instance, if you make access at the Library level, then you would add an association between the user and the library. This can be a 1:1, 1:many, many:many, whatever your data model requires. The key is that joining through this level will always return no records, thus your entire query will return no records.
Example, assuming a user can only belong to one library.
User table has LibraryID, Books table has LibraryID, This makes an effective many-to-many join between Users and Books. So you join User and Library on LibraryID, and join Library and Books on LibraryID, then only books that belong to a library that the user is associated with will be returned by the query.
In this way, it becomes impossible for a user to query anything they are not directly associated with. The security is entirely in the database, and no business logic is required.

Advanced .NET Membership/Role Provider

I'm in need of a RoleProvider with the following functionality:
Dynamic Assignment of Roles to Tasks
Authentication / Authorizaiton of IPrincipals based on the dynamically allocated tasks in the system they have privilege to access
Reporting showing who is currently logged in, and other common usage statistics.
I'm pretty sure I'm going to have to roll my own, but wanted to make sure I didn't miss out on something OSS or even from MS.
I'm also using ASP.NET MVC and so my basic plan is to write a custom attribute like: [Authorize(Task=Tasks.DeleteClient)]
and place it over the methods that need authorization.
Rather than authorizing against the Role, I'll authorize the task against the role based on whatever settings the user has configured in the DB.
Thoughts?
You might want to check out NetSqlAzMan. It allows you to define tasks and assign them to roles and then authenticate and authorise your IPrincipal objects.
You may need to roll your own security attribute but NetSqlAzMan should help make that a reasonably easy task.
We had a similar issue with one of our systems. The first thing I'd do is create more AuthorizeAttribute classes for your specific tasks - e.g. DeleteClientAuthorize etc. You can then add specific logic into your classes.
As long as you can access the routines that trigger the change of roles for the current user you should be OK. Just call Membership.DeleteCookie() and this will force the next authorisation request to re-query your data store. It's at that point that you can determine what roles are required now.

Roles for white-label service access

Okay,
I know I'm doing something wrong - but can't figure out a better way.
I am developing a website which is going to allow users to setup their own mini-websites.
Something like Ning.
Also, I have only 1 basic login and access to each mini website is provided (right now) via roles.
So the way I am doing this right now is:
Everytime a new mini website is created - say blah, I create 2 roles in my application.
blah_users and blah_admin
The user creating the mini website is given the role - blah_admin and every other user wanting to join this mini website (or network) is given the role - blah_user.
Anyone can view data from any website. However to add data, one must be a member of that mini site (must have the blah_user role assigned)
The problem that I am facing is that by doing a role based system, I'm having to do loads of stuff manually. Asp.Net 2 controls which work on the User.IsAunthenticated property are basically useless to me now because along with the IsAuthenticated property, I must also check if the user has the proper role.
I'm guessing there is a better way to architect the system but I am not sure how.
Any ideas?
This website is being developed in ASP.Net 2 on IIS 6.
Thanks a tonne!
I afraid standard roles-related stuff of ASP.NET is not what you need. You can try to change authentication module so it will:
Log you in with cookie.
Determine what roles does your visitor have. Perhaps you will use some special table that corresponds user and site.
Make custom principal with user roles enumerated and assign Identity and Principal to the current request.
I also don't think that making special roles for each site is good idea. When you would have hundred sites, you would also have two hundred roles. Pretty unmanageable, I afraid.
When we were solving similar task, we were just not using standard controls. We had single set of roles used on all sites. Membership of concrete user is determined according to current site and his relations to this site.
Addition: Another possibility to investigate is Application that exists in ASP.NET authentication system. Maybe it's possible to isolate each subsite into separate application?
Update: Method that works for our application.
Do not make a lot of cloned roles. Use only two: users and admin. If your sites are public then "users" role could be just global - user on one site doesn't differ from user on another site. If "users" and "everyone" are different roles, then of course "users" should also be bound to a site.
Use standard ASP.NET Membership users, but do not use standard role mechanism.
Make a mechanism for storing relation between site and user. It could be simple table that holds site id, user is and role.
What you have to override is IsInRole method. (Methods to be exact, i'll cover it later). This method is in IPrinciple interface, so you have to make your own principal object. It's quite simple.
Method IsInRole of this type should look take current site (from HttpRequest) look into the site-user table and get roles
Then you have to associate your principal with a request. Do it in PostAuthenticateRequest event.
There is also RoleProvider. Honestly I'm not sure when is it used, but it also have IsInRole method. We can override it in the same way. But other methods of this provider are harder. For example AddUsersToRoles. It accepts array of user names and roles, but to what context (site) should it be added? To current? Not sure, because I don't know when this method is called. So it requires some experiments. I see (Reflector helps) that RopePrincipal by itself uses RoleProvider to fetch list of roles, so maybe it's implement only RoleProvider, using standard principal. For our application this is not a case, so I can't say what problems could be hidden here.

Resources