I just wanted to compare different solutions used when implementing ACLs in Rails.
I use the authorization plugin (Created by Bill Katz):
Roles can be authorized for the entire application, a model class, or a specific object. The plugin provides a way of checking authorization at the class or instance method level using permit and permit? methods. It also provides english-like dynamic methods like "user.is_manager_of project" (where "user" acts as authorized, "manager" is a role, and "project" is an authorizable model). You can specify how control is redirected if authorization is denied. (quote source)
Homepage:
http://www.writertopia.com/developers/authorization
Docs:
http://github.com/DocSavage/rails-authorization-plugin/tree/master/authorization/README.rdoc
You might also be interested in reading this comparison (from last year but still somewhat useful; it's where I got the above quote from):
http://www.vaporbase.com/postings/Authorization_in_Rails
And a more recent comparison:
http://steffenbartsch.com/blog/2008/08/rails-authorization-plugins/
The best I've found is role_requirement. It plugs straight into the restful_authentication plugin.
There's a plugin called acl_system2 which operates by having a users table and a roles table. There's a lot more useful information in the README and the project is on github too.
Related
I recently started working with Wolkenkit and I was wondering if there is a possibility of implementing some sort of role concept yet?
I already found Wolkenkit: ACLs for authorization and user roles which is already quite interesting, and gives me a first idea on how to solve that, but at the same time it is not exactly what I need.
In my Use-Case I need a dynamic role concept which can be changed at any time in order to grant and revoke access to certain parts of my application.
Ideally it would be a mechanism that allows me to associate commands and events with multiple roles at run-time. Are there any new approaches on this topic or any examples where this is already done?
Thanks for the help in advance.
The authorization concept of wolkenkit is based on tokens.
Hence, the simplest thing to do is to have the identity provider add claims for roles, as described in ACLs for authorization and user roles (which is the article you already linked to). This works out of the box, and you do not have to provide and special logic to your wolkenkit applications except to read the token and evaluate its claims. However, this is only suited for static role models, as you'd need to change the identity provider's configuration every time a role assignment changes.
If you require a more dynamic approach, right now unfortunately you are left to your own devices. What you could do is to add a property to your aggregate that contains an array of roles (or user IDs) that you want to be able to access the aggregate. Then, in each command, you would need to check the current user against this array. But still, this means that you have predefined roles, you just could allow or restrict access to aggregate at runtime for specific roles.
If you require an even more dynamic approach, such as making up roles ad-hoc, e.g. to share data with a group that you just want to create at hand, you end up with what we call group-based authorization. Right now, there is no support for this, and AFAIK nobody has yet implemented something like that. Support for this is on the wolkenkit roadmap, but right now unfortunately there is no ETA available (maybe this is something you could contribute to wolkenkit?).
Either way, you need to make sure that your identity provider is configured correctly and wolkenkit is setup accordingly, as described in wolkenkit redirects to Auth0 even when user is logged in.
Disclaimer: I'm one of the core developers of wolkenkit, working at the native web (the company behind wolkenkit), so please take my answer with a grain of salt.
I have Users which create HomeRepairTickets.
Firms can create TicketBids for HomeRepairTickets they are interested in.
Should my controller spec ensure that Firms can only bid on HomeRepairTickets they have access to? And make sure they can only update HomeRepairTickets that they created?
Or is there a better way to test appropriate authentication (eg that the ids match or that the authentication_token matches)
I'm using rspec.
You should use externalized authorization / attribute-based access control (abac).
ABAC is an authorization model defined by NIST that lets you describe authorization requirements in terms of attributes and policies. Based on your question, you would want to implement a policy along the lines of
A user can view a ticket if the ticket belongs to the same firm as the user.
With ABAC you can have as many policies as you like. There is a standard called XACML that implements ABAC but I do not believe there is anything in Ruby that implements XACML.
Your best bet is the CanCanCan gem which provides you with similar capabilities. Check it out here.
The short answer to your question is 'yes'.
"Firms can only bid on HomeRepairTickets they have access to" and "Firms can only update HomeRepairTickets that they created" are good functional requirements (aka system behaviors). You should definitely be testing at this level.
Now, you may decide to test at lower levels (e.g., tokens/ids matching, etc.) as you go along developing, but it's always good to come back to testing your high-level requirements and make sure your system is well-behaved.
Whether or not your authentication lives in a controller is a whole other topic. As is how you choose to represent your authentication logic. But, it's all good stuff.
I'm looking for a plugin that provides a role based authorization mechanism for securing read/write access to attributes. I'm picturing something along the lines of declarative_authorization for white listing attributes of model objects. I've spent some time looking around but have come up short, does anyone know of anything?
EDIT: I'm using declarative_authorization to control which users have access to what actions in the controller, but I need something similar that provides access control to the attributes of each model object. I'm trying to prevent information leakage through the web API or users from crafting malicious posts. I can do this through the mass_assignment_authorizer but I was hoping some plugin did this already.
CanCan Branch 2.0
https://github.com/ryanb/cancan/tree/2.0
Edit:
The continuation of CanCan is called CanCanCan.
See https://github.com/bryanrite/cancancan
What about creating a model / controller pair for each controller, and then allowing each role only to access methods in its controller(s)? Then you can make a before_filter in each controller that makes sure each user has permission to use methods in that controller.
I know there are role based authorization gems/plugins for rails to determine if a user can do things based on which role their in. However, is there a best-practice approach to hiding actions from users based on ownership? ie: the show/edit/destroy methods for a user should only be available if they're being performed on the currently logged in user id. Hopefully that makes sense, but I've written some methods to protect against non-owners accessing methods and its become a bit bloated and ugly.
Look at cancan's implementation.
I can recommend on restful_authentication( https://github.com/technoweenie/restful-authentication ). quick tutorial http://railscasts.com/episodes/67-restful-authentication
I am building a project management app and I am not sure which is the best/correct authorization model to implement given I am new to Rails (and programming in general). Here is what I am trying to do.
I want to be able to add a "client" to the application and then multiple projects to a client. I would like to be able to add users (that are essentially representatives of the client) to view that clients multiple projects but not other clients. I intend on having controllers for time tracking, notes, comments and images all to be associated with both clients and project of that client.
In addition, I would like to set up the account to control who is able to have one. I don't need the user to establish an account on their own.
Does that make sense?
I believe what you are mentioning is called Authorization not Authentication, anyway:
I would suggest acl9 for authorization and authlogic for authentication.
These (free) Railscasts should give you some food for thought. There are lots of great RubyGems/plugins out there for this sort of thing.
The Ruby Toolbox gives you an overview of tools and their popularity in the rails community (rated by watchers and forkers on GitHub). As you can see there, the suggested plugins restful_authentication and authlogic are almost on the same level.
Restful Authentication is still the golden standard for user authentication in ruby on rails.
I have used Authorization plug-in in the past and like it because it gives some nice meta methods such as:
user.is_eligible_for_what --> returns array of authorizable objects for which user has role "eligible"
user.is_moderator_of? group --> returns true/false
user.is_moderator_of group --> sets user to have role "moderator" for object group.
user.is_administrator --> sets user to have role "administrator" not really tied to any object.
There's also a brand new RailsCast on CanCan.
I'd use AuthLogic for authentication (logging in users and making sure they are who they claim to be) and declarative_authorization for authorization (making sure they have access to resources). See Ryan Bates' excellent Railscasts on AuthLogic and restful_authentication for more info.