Extending role based security to allow roles for a specific entity - asp.net-mvc

I've used FluentSecurity in another MVC application and its great, provides a slick implementation.
I now have a requirement to offer application wide roles, plus also provide additional permission control over individiual entities.
My application manages particular locations and a user may have permissions to perform actions at one or more locations, each location has a unique id. I'll need to check a user has a particular role for the location id (effectively adding another dimension to roles). I've got my schema mapped out, along with my repo/service layers.
I was wondering if someone has tackled this type of problem before and whether its worth me trying to solve with FluentSecurity or if I should validate the user has the role required for the location on each GET/POST request (controller or service layer).
I'm getting to achieve this in FluentSecurity I'll have to roll my own policy and capture the location id from the RequestContext.RouteData.

I haven't done exactly what you need to do, but creating a custom policy in FluentSecurity that handles your scenario should not be hard at all. If you feel it is, please let me know and I will have to fix that.
You can find more information on how to create custom policies here:
https://github.com/kristofferahl/FluentSecurity/wiki/Custom-policies
It sounds to me like you might want to split it into two custom policies. You then apply your custom policies like this:
configuration.For<SomeController>()
.AddPolicy<CustomPolicy1>()
.AddPolicy<CustomPolicy2>();

Related

Changing a lot to config new permission

What is the best way of dynamic authorizing users with their roles. Indeed I have some roles that changes overtimes and currently I have this code for some of my actions or contorllers:
[Authorize(Roles = "Admin,MainFedration,FederationUser")]
public string ConfirmAccident(int? id)
{ .... }
Then if a role add or change it's permission i should search and change most of actions and roles to config new permission.
What is the best way to remove this redundant work?
The only other way would be to configure the permissions each role has in a database and then subclass AuthorizeAttribute and overload the logic for how it determines which roles are allowed by utilizing the database-stored permissions.
However, it should be noted, that this is a problem mostly because you're using roles improperly. I see this all over, even in official Microsoft documentation, which is part of the problem. Something like "Admin" is a group; roles are different and should be things like "CanEdit". A group or a user can be assigned roles, so any user in the "Admin" group, would have the role "CanEdit". Then, you don't have to change the roles config on the action because the ability to edit is the ability to edit, no matter which users or groups have it.
Maybe you should take a look at how Access Control is organized: https://nsecurity.codeplex.com/. Here's a simple solution which outlines the principles of Access Control Entries, Access Control Lists, and how access to items, subject to security restrictions is set up. This way of (dis-)allowing users' access to certain items is much like the way it is organized in, say, Windows file system.
The idea is really simple: instead of giving user permissions (not) to do this or that, the items are guarded and access is granted/denied once a simple condition is satisfied. In other words, security is not geared towards users, but towards "securables". Or, keys are used to lock/unlock doors, but not to prevent users from moving around.

Determining and persisting the current tenant in multi tenant web app in Rails

I'm contemplating a multi tenant application - shared database, shared schema. A tenant identifier (tenant key) associates every row with the right tenant.
What i'm not sure about is how to go about loading the tenant_id into some sort of global scope. How should this happen? I assume that I would parse the domain and then look up the tenant_id based on the domain.
My questions:
Where would the lookup happen in a rails application? In an initializer? Is there a better point to do this?
Once I have determined the tenant_id, what is the best way to persist it - a simple session_id?
I use a before filter for the controllers for this function.
You can also sub-class the controller class to DRY out duplicate code in the controllers.
Be careful to remember that access to a given tenant's information needs to be authenticated on a per-user basis. You need to decide if a given user will have access to more than one tenant. Eg should user "joe" have access to tenants 1 and 2? Or should Joe need a per-tenant login?
The login's authorization should control access to the tenant info. Don't rely on the domain name to grant authorization.
Re: where to persist the tenant_id? Store in the session. If access to the session is expensive (stored in DBMS), then make an in-memory copy as an instance variable during the controller startup. Google for how user_ids are often stored.
You also should determine the user experience for if/when a user wants to access a different tenant.
Added To see which welcome screen to load before the user has logged in, looking at the subdomain name is a good choice. To see which subdomain the incoming request used, parse request.fullpath() Docs. Do this in a controller filter.
Since the authorization comes from the user_id, remember to test the case where joe logs in at tenant1.app.com but only has access to tenant2.app.com
Bonus answer Looking for a templating system that will enable your customers to have full control over their tenancy's user interface? Check out Liquid templates. I was very successful in using them to enable my customers to have full control over their look and feel in a safe way.
Re additional questions in comment
See superuser for configuring the web server. The config is web server-specific.
If you want the welcome screen to not be generic, then you must know from the request url how to customize it. Tenant-specific subdomain is the nicest. If no subdomain, then show the generic welcome--when the person logs in you can determine the tenant and how to customize.
Re helper--if you mean a view helper, then I would not recommend it as the primary place where the tenant is determined. Make the #user and #tenant be light-weight models that you look up once and then retrieve from the session during additional requests for the same session. The models will be used by the controllers and, perhaps, passed to the models. The View layer will also be able to see them and use them as necessary.
If the UI may look/will look completely different for the different tenants, then add a "tenant-display" layer in addition to the view. Eg have the view gather the instance variables, find the right Liquid template, then express the view via the template.
You don't want the view to be computing "if tenant_a then x else y"

Group permissions for a website using spring security - design query

I am creating a Grails website where users will have access to the resources they create. Till here everything is clear to me. I define ROLE_USER and lock down my controllers and actions using the Config.groovy file.
The issue I am facing is that I have requirement to support group of users such that some resources created by a user can be edited/updated/deleted by other users of the same group. How do I associate a user with a "group" in spring security, what is the design/library I should use here?
What you will need to do is to have your users' roles (the authorizations) come from the database. Once that is the case, you can then easily adjust the roles a user (or set of users) has and create/remove them on the fly. The docs have some pretty good info on how to get the roles to come from the database, so I won't go any more into that here.
Once the dynamic roles are in place, however, you still need to be able to connect roles to the objects that are created. There are essentially two ways you can go about doing this:
Access Control Lists
Custom logic
Depending on the granularity you need and the flexibility you want, one option may be more appealing than another.
Access Control Lists essentially allow you to have a permission mapping between each user and each entity instance. As you can imagine, it's a fair bit of overhead and can perform poorly if you have a large number of entities and users.
Putting together your own logic, on the other hand, is much more flexible because you can set up your own scheme to connect entity instances or entity classes to users and their roles.
I dont think that spring-security provides such functionality out of the box so you will have to do that manually.
For each domain class that you this kind of functionality, store the user name of current logged in user
def authenticateService
def user = authenticateService.principal()
entity.setUser(user?.getUsername())
Then in the update/delete method of the contoller you should check if the role of the current logged in user matches
the role of the user that created the entity. If you have a match you should proceed with the update/delete otherwise throw an exception
/redirect the user to an error page
As role you can use the spring security roles or you can create a property on the user object you have created

Vaadin appfundation authorization

I'm using vaadin for my project.I have implemented the User authentication using vaadin appfundation plugin,I need to apply role base access(Authorization) to the my application,But I don't know how to implement this functionality in appfundation,I searched a lot on the internet but I couldn't find a good example for that ,If any one knows how to implement that function pleas let me know,As I understood I want to implement Resource ,Role interfaces in appfundation,Please help me to solve this problem.Thnxx
You need to start by initializing a the Permissions class using a PermissionManager. So the first question is, how are you going to store your permissions? For example, if you are going to store them using JPA and AppFoundation's persistence module, then you can use the provided JPAPermissionManager. To initialize the Permissions class, call
Permissions.initialize(application, new JPAPermissionManager());
If you are not going to use JPAPermissionManager or the MemoryPermissionManager, then you need to implement the PermissionManager interface yourself and initialize Permissions using it.
The next step is to implement the Role and Resource interfaces. The Resource interface has just one method you need to implement, getIdentifier, which returns a unique string for a resource. A resource is whatever you want to protect, for example, a view. The Role interface also has a getIdentifier method which needs to be implemented, you should return a string which identifies a specific role, for example, "admin", "normal user", "power user" etc. The Role interface also has some other methods for handling role relations.
Unfortunately, the documentation is uncompleted and the best source available is probably this wiki page http://code.google.com/p/vaadin-appfoundation/wiki/Authorization
You can also try to take a look at the tests for the Authorization module, those might give you an idea how to use the module :(

Grails Shiro plugin : confirming my understanding

I'm bit vague about how to start using the shiro plugin, after reading few documents. I decided against Nimble, as it comes with few tables and UI plugins.
I setup shiro plugin with wildcard realm, with my own tables. I may use permission based (rather tan role based) access control as it scales well. Now, the steps for it.
assign the permission string to the subject, and save it in the db
check the permission through isPermitted, hasPermission (or relevant tags in GSP).
Now,
1. when to use the accesscontrol through filter?
2. is there a closure injected into the controller where I can define the permission for the actions in it? I read somewhere about accessControl static closure on each controller, but not seems to be documented.
3. How do I create a typical access control scenario like only the creator of (something, a post etc) can delete it? One possibility is creating and persisting a permission string based on userid. to check the permission retrieve the object (post), get the userid and compare with subject.. seems bit complicated.. any easy implementation?
thanks a lot..
Babu.
1 when to use the access control security filter?
A. Use accessControl{true} when you want to limit access to controller actions to authenticated users.
B. Use accessControl() when you want to limit access to controller actions, regardless of parameter content, based on permissions "${controllerName}:${actionName}".
C. When you want to limit actions based on parameter content, e.g. only delete a domain object for which you have the delete permission "${name}:${id}:delete", you need to check isPermitted explicitly in the controller.
3 How do I create a typical access control scenario like only the
creator?
I would add a the necessary permission(s) to the user when the post is created, e.g. "post:${postId}:*" This way the permissions belong to users and/or roles, and not to arbitrary domain objects, as intended in the Shiro way of working. As opposed to file system permissions, which belong to files and directories instead of users.

Resources