.NET Role Based Access with Resources - best practice - asp.net

I am developing a .NET MVC application, and currently using only Role Based Access Control. I am wrapping my controllers endpoints with [Authorize(Roles="Provider")] for example.
Now, I want to add the add permissions on resources as well, e.g. not only saying if a user can edit a document, but also to define which documents it can edit.
So I want it to look something like -
[Authorize(Roles="Provider")]
[Authorize("CanEditObject1")]
What is the best practice for doing so? What type of authorization is required here? Perhaps I need to mix some (Role Based Access + Policy Based Access)? Do I need to change my whole Authentication method or just add on top of it?

You will want to look into Policies. I too got schooled on this pretty fast when I tried submitting a PR for authorization tag helpers and never got back to it. In short define policies at your composition root and check those with Authorize attributes.
Row level access may require additional checking however unless you can establish membership levels.

Assuming that the authorization at the controller level is read-only, a more restrictive "Edit" role could be enforced at the controller's edit methods by using an authorization attribute on the edit methods. I would also conditionally hide links to edit methods in the view from end users without that role. Another option is to leverage claims that the authenticated user has to discriminate their access to certain resources.

Related

How can I use OverrideAuthorization globally to authorize a specific role in MVC (without forcing authorization over the entire program)?

I'm working on a web application where I want to implement authorization at the controller level using roles. I plan on having multiple controllers, with most controllers utilizing a specific role for authorization. My issue, though, is that I also want to have a role that can be used globally across all controllers and actions. How exactly can I do this?
I've seen a TON of articles on locking things down the opposite way. For example, I know you can go to the FilterConfig.cs file and add a line like this:
filter.add(new AuthorizeAttribute() {Roles = "Administrator" });
But I don't want to approach it this way! This makes it so that every action must have the Administrator role. On top of that, if I use this the only way to get what I want in the controller is then to do:
[OverrideAuthorization]
[Authorize(Roles = "MyControllerRole")]
Some controllers I don't want to use any authorization on, and others I only need to use authorization on a few actions. If I use the above global authorization, I'd have to put this override on every single controller!
Is there some kind of special global override authorization where I can tell my program: "regardless of what roles are used for this controller or action, if the user has the 'Administrator' role they can access this action"?

Is it possible to validate a querystring ID, for ownership, in FluentSecurity?

Just discovered FluentSecurity. Looks very interesting.
My Web Application is written in MVC3, C# and Razor.
I am worried about the URLs being tampered with. So on top of checking for authenticated users, correct roles, I also need to ensure that the user is not trying to tamper with the URL to view data that he/she has no access to.
ie He/She owns #10, so
Order/10
is fine,but not:
Order/100
With the standard [Authorize] one could write a custom authorisation class that inherits from the Authorize class which thens check the ID which is okish... and works.So if ID is owned by user then return true. How would this be implemented in the FluentSecurity environment?
Many thanks.
I can't tell you how to implement it but I can point you in the right direction.
What you need is a custom policy. You can then set up a security context modifyer to provide you with the querystring/route data you need.
Custom policies are covered here:
https://github.com/kristofferahl/FluentSecurity/wiki/Custom-policies
Security contexts are covered here:
https://github.com/kristofferahl/FluentSecurity/wiki/SecurityContext

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.

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