I'm working on a project that needs to have flexible authorization. What I mean by that is this:
My users will be divided in to client groups, so each client could have many users.
Each user needs to be able to have different roles, but the definitions of these roles needs to be able to be set on a per client basis, and ideally in a way that, say, a user with an ultra_admin role would be able to edit the roles for her client group.
I've looked in to the following:
CanCan
Declarative Auth
acl9
and a handful of others, and I can't see a way to do this in them, although I think it's probably possible in acl9 it doesn't look like it's what it was designed for.
Is there an existing authorization gem that makes this easy? Is there a reason that this isn't out there (i.e. am I missing an obvious solution that is simpler)? If it's possible with one of the above gems is there an example anywhere?
I couldn't find anything like this either, and so I rolled my own.
https://github.com/PRX/badges
I'm working on an update, and rename, which will work very much the same way and be out soon, but this version on github we use in production.
Related
So I have decided to rewrite an application I have been writing in Node.js to Elixir because of all the extra complexity working with Node that Elixir comes with out of the box.
My issue was something I didn't have quite right in Node and is becoming just as complex in Elixir and I am not entirely sure how to go about approaching it.
I am trying to recreate a lot of how Discord does permissions. I am essentially building a CRM system, with different roles like "Sales Manager", "Sales", "Customer Service Rep" etc... But they all are able to do different things based on their "role".
Some things I need to do is be able to update a permission on the fly for a person or role. Maybe the "Sales Manager" role can't look at company financial data like an "Accountant" but we need to give that specific person access for a few days. Or I have a "Customer Service Rep" and we give that entire role the ability to add things to a calendar. I also would like to have the ability to kill sessions.
So there are a few ways I've seen said around Elixir forums, like:
Using Guardian, I really want to like tokens and think not having to hit the database every time sounds wonderful, but I don't think it's practical for this. Unless there is a good solution to updating tokens on the fly which I haven't found.
Giving each person their own process and just kill and start the process on changes with new changes. This seems pretty neat, but I'd rather not kill processes unless there is an actual error, I think this solution will come with big problems, like tracing problems. Although I am not familiar enough to know if this might actually cause problems, or if this is a bad solution for other reasons.
Use Guardian with Guardian_DB, which then defeats the purpose of using tokens, but at least I'd have a trackable session. My only problem with this is I do plan on using a load-balancer so that if a socket connection dies I can reconnect it to the same server and I am not sure there is a way to do that with tokens or if the socket itself has a session attached to it. This is not really that big of an issue though and is pretty close to what I had with Node.js.
Use Redis which I'd like to stay away from, and then update session data in Redis based on user_id when updates occur and hit Redis on every request to see if the user has permissions. I plan to put this across multiple servers eventually which means ETS is not viable unless I can load-balance socket connections like I could in Node.js.
So I guess my questions are,
Can I attach sessions to sockets? Is this a bad idea?
Should I still use a token, and just use Redis to check the token on every request?
Is a token still a better choice than a session?
Is there a much better/easier solution that I have not even mentioned?
I'm sorry this was pretty drawn out and long, I've never had to do something as permission bound as this project professionally and am pretty new to Elixir.
Phoenix channels are stateful. You can put data in the assigns field and it stays there for the duration of the connection. That is where you normally put your user_id after authenticating the user on join.
I also use the channels assigns to store client state that I need on the server.
WRT to the role to permissions question, I'm doing exactly this. What I do is load the load the role permissions from the database on startup and build an ETS store with them. You can do the same with a Task or a GenServer. If the permissions change for a given role, i update the database and the ETS table.
My user model supports a list of roles for each user.
When in need to validate the permissions for a given user, I call the Permission model api like Permission.has_permission?("create-room", user, scope). I have two level of permissions, global and per room. That is what the scope is used for.
I'm trying to implement a claims-based authorization setup using Web API/OWIN/OAuth and I'm trying to find out the best way to manage a more fine-grained type of authorization.
I don't like the idea of using just roles, as there needs to be lots of fine-grained authorization in the application I'm working on. I was thinking a roles+permissions approach made more sense (where a role simply maps to a subset of permissions). The permissions would be based on an action+resource pair (e.g. CanViewEmployee, CanEditEmployee, etc.). Nothing out of the ordinary here.
However, I'm wondering how this should be implemented using OWIN/OAuth, possibly using Thinktecture IdentityServer. I am trying to avoid hard coding the permissions in the custom AuthorizationManager I have as they need to be easily changed without a rebuild. I know it is an option to put these as policies in the web.config (mapping a resource+action to a claim type and value), but if we are talking about dozens, maybe even hundreds of permissions, this seems like it could get out of hand pretty quickly as well.
I guess the third option would be to drive it all from the database, but managing it from there would also need some kind of front-end to do so, which is more effort than just changing a config/XML file.
Am I missing some other options/best practices here when it comes to large numbers of claims/permissions, or perhaps some other utility or package I could use to help manage this when the numbers get out of hand?
Decoupling these permissions into a separate authorization manager class is a good first step. In that code you could then hard code the rules for your permissions (such as "Admin" role can do action X, Y and Z, but only "Manager" role can do X or Y). But you can also have the code in the authorization manager perform dynamic look ups to check permissions that have been set in in a database (for example).
The additional benefit of doing this in code is that you can unit test it all to prove your permissions logic is implemented correctly (and thus will be properly enforced at runtime). This will be useful if your permissions do change frequently.
Also, the decoupling will help if you need to redeploy frequently (because of the frequent changes), since the code can be isolated into its own assembly.
I've got several sites that I'd basically like to have the same user system for.
One of the sites runs XenForo, the others all run Codeigniter, or systems built on Codeigniter (e.g PyroCMS).
I need to somehow be able to let a user login on any of the sites with the same username/password combination, in addition to be able to register.
I know there are a number of ways of going about this, such as an OpenID server, however I'm not 100% sure which is best for my situation given that I'm using two systems that arent exactly going to play nice together.
I'm not too bothered about having it autologin across all sites at once, but just dont want people to have to use multiple different credentials.
Would I be right in thinking something along the lines of a central OpenID server, with openid authentication on the 'slave' sites would be my best option?
I'd ideally like to use the XenForo user table as the 'master' user table in this situation.
Any input or suggestions would be greatly appreciated.
I wrote one here a while ago, I've not updated it in a while though should still be good :
http://www.jeremyhutchings.com/2010/12/xenforo-and-codeigniter-intergration.html
I'm making a website for a client and Joomla, I want the client to be able to manage users on the site / delete them if necessary, but that is it, I don't want them to be able to see or do anything else on the site, what is the best way of doing that?
Ideally I would have liked to have this done through the front end, I was looking to make a simple list osf users that only the admin group can access and manually delete them from the DB directly, but I'd rather do it through Joomla if that was possible for security reasons.
I looked at ACL's a bit but couldn't really figure out how to limit the functions to what I want, any help is really appreciated.
From the front end you won't have much luck with that. As far as user management all of that is handled on the backend.
If you're looking to do that sort of thing you'll simply have to get much more familiar with the ACL - there's a good amount of documentation on www.joomla.org
Even by utilizing the ACL I don't think there will be much you can do to limit a particular group to having access to JUST the userbase specifically. The best bet would be to educate your client about Joomla, how it works, what to change, how to change it and why to leave everything else alone. I know that may be problematic for things in the future, but unfortunately I don't know of any (and have not heard of any) front end solutions for what you're looking to do. I haven't heard of any back end solutions either however.
I think certain things will be so intertwined to certain levels of permission you won't be able to have that kind of granularity.
**edit: I'm almost 100% positive there's no way this is possible on 1.5.23 (or earlier versions) because the ACL simply isn't there. So my advice above is aimed specifically at versions up to 1.7.
We're building an application designed to run on Windows-based servers. One of the considerations we're looking into at the moment is how to control access to the application's GUI, which allows configuration and controls the "back end" services.
In order to secure the application properly, there are several objects which will need ACLs to be applied - files, directories, Registry keys, named pipes, services etc. We need to provide administrators with some way to configure those ACLs in order to limit access to authorized users only.
One approach we have considered is to create a tool which can modify the ACLs on all those objects simultaneously, but that would be a fair chunk of work and could be fragile.
The other possible approach we're looking at is to create a custom group (e.g. "My App Users") so we can give that group the appropriate rights to each object. This means that administrators will be able to add/remove authorized users by using familiar Windows group membership tools.
So: is creating groups at install time an acceptable thing to do, or is it likely to upset administrators? I'm more familiar with the UNIX world, to be honest, where server-based apps are more or less expected to create groups, but I'm uncertain of the etiquette in the Windows ecosystem.
Also: is there a better solution to this that I've missed?
Thanks in advance!
The question is twofold - one technical, and one political. Technically a local group is fine, you can add AD or domain users into a local group and everyone's happy. In terms of whether an app should be messing with a server's security 'stance', the only reasonable answer is to pop up some kind of request telling the user what you are going to do and asking permission (make sure you also document the decision in some kind of log or entry). This also addresses everybody's legal a$$ eg if they click "no, leave my app unsecured" and get hacked).
Taking a UNIX approach, you could tell the user what you need, suggest a local group (and give the user the chance to pick another local or domain/AD group). Take a look at how (eg) Oracle installs on UNIX do it.
Since this is a server app and you might have to support silent/unattended install, make sure that the behavior can be specified in the install script and very, very sure that the behavior of the script is documented so that no one installs the program without realizing the change in security policy that the installer implements.
I think it's perfectly fine to create a local group for this purpose.
Furthermore I have not been able to come up with a better solution after giving it some thought.
Depending on the size of the implementation, groups could be the way to go.
But please keep in mind that the relevant ACLs on directories and the registry ought to be set. I do agree that setting them once to the group and then let access control be maintained by group memberships.
In regards to klausbyskov's answer, I think a local group could be fine, but consider using LDAP instead. From a security perspective you would detach the authentification process and let the Directory handle it; using kerberos.