Why does Spring Security's RoleVoter need a prefix? - spring-security

In our application we planned to use the RoleVoter mechanism but we'd like to remove the ROLE_ prefix as the security we are implementing is more task based than role based.
Technically, there is no problem for the implementation but I found in the documentation that using the RoleVoter with an empty prefix should be discouraged.
I'm wondering why?
AFAICS, the only problem is that, without the prefix, the RoleVoter will participate in decisions that it is not meant to (such as the IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED, ...) and might returns an access denied instead of an abstain.
Could you please confirm that this is the only issue with an empty prefix?
Thanks in advance
M.

Yes. If you are using multiple voters or a custom voter then they need some way knowing which attributes they should consume. For example, if you have a DayOfTheWeekVoter and you have a resource defined with attributes ROLE_USER,DAY_MONDAY then the RoleVoter might vote to grant access because the user has the role "User", but the DayOfTheWeekVoter might deny access because it is not a Monday.
If you don't configure RoleVoter with a prefix then it would check if the user has the authority named "DAY_MONDAY" assigned to them, and so this scenario won't work.
If you are only interested in roles, then you can do without a prefix, or you can use expressions (such as hasRole('user')) which don't use a RoleVoter.

Related

Implement a role and authorization concept with Wolkenkit?

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.

Enforcing restrict on current user by default

We're looking at the protector gem for attribute level security. I'd like to auto restrict all models to the current user by default so you have to explicitly unrestrict it instead of the other way around. So..
Article.find(3) # Is actually eq to Article.restrict!(current_user).find(3)
But finding it a little challenging to implement it without wrapping/proxying the model. Was wondering if anyone has done this or has an idea of how to implement that type of functionality.
From the protector documentation:
Protector is aware of associations. All the associations retrieved
from restricted instance will automatically be restricted to the same
context. Therefore you don't have to do anything special – it will
respect proper scopes out of the box
You need just to restrict the current User itself.

Need an advice for per user based ACL

Currently I'm working on system, that uses ZendFramework2 Acl implementation for managing user roles and permissions for various parts of it. Till this moment it works as is supposed to do - giving or rejecting users based on their role. Recently we got a new feature request - implement functionality that allows permission management per user, regardless the role he or she has. Here comes the tricky part - Zend implementation of Acl doesn't met the requirements out of the box (if it supposed to do so at al). Just to note - system is already tightly integrated with the current model, so it will be pain of heart to use another kind permission management model.
So far the best solution I could think of was to represent individual users as roles in Acl and grant them appropriate privileges, so it is possible to dynamically create or delete resources and privileges for users, without impacting overall role permissions (which still apply).
Could I get some suggestions please? Is this the "right way" or there better approach to the problem? Thanks in advance :)
If an user by the fact to be himself has some privilegies, then you have to create a new role for that user.
I have just developed an ACL module that allows you to manage access to each route only creating a new key in each route called 'roles'. You do not have to configure the ACL creating allow rules manually, this module creates the rules automatically for you reading the routes.
You can have a look: https://github.com/itrascastro/TrascastroACL

Was mass assignment really the culprit in Homakov's GitHub hack?

Many commentators (e.g. ZDNet) have suggested that the weakness in GitHub's case was that the model Homakov discovered was vulnerable had mass assignment enabled for its attributes.
However, I think the problem was not this, but was rather a failure to use a before_filter (or suchlike) in the controller to ensure that any given row in the table he updated could only be updated by an admin or by the user with the ID listed in that row. If such a filter had been in place in the controller, then the table would have been secured from attack even if the model's attributes were mass assignable.
Am I correct?
Yes, I think you're right.
In such situations, you can also use authorization gem, for example: cancan, declarative authorization, heimdallr...
The problem is not that you can use. The problem is how to help do not forget to use it in certain situations. For example cancan have the following method: check_authorization It helps to check authorization for all actions.
About that says Homyakov. Add the protected attribute would be the easiest way. Maybe vulnerability has been discovered just because solution to restrict the authorization was different. In some situations, adding of protected attributes leads to a loss of flexibility in your api.
As far as I understand this issue has nothing to do with before_filters checking for admins.
An attribute existed, in the exemple you cite the user_id on the public_keys model, that was not supposed to be exposed to mass assignment.
The before_filter can work as another "layer" of security as .slice can be also used to ensure that you only get the attributes you supposed to get can also work.
On a last note: I think admin != god, meaning, I find no use to a Github admin having rights to perform the action Homakov was able to perform exploiting this issue.

What's the best way to implement ACLs to a Rails application?

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.

Resources