OAuth2 and Role Based Access Control
I have a Rails application acting as an OAuth 2.0 provider (using the oauth2-provider gem). It stores all information related to users (accounts, personal information and roles). There are two client applications that authenticate through this application. Client applications can use the grant type client_credentials
to find users by email and perform other actions that do not require an authorization code. Users can also log into client applications using the provide password type.
Now the problem we are facing is that user roles are defined globally on the resource node. Therefore, if a user is granted a role admin
on a resource host, that user is admin
on both clients. My question is, what do we do to have finer access controls? That is, the user can be editor
for app1
, but not for app2
.
I think the easiest way to do this - change role names as follows: app1-admin
, app2-admin
, app1-editor
, app2-editor
, etc. The big question is: will we implement this whole system correctly; that is, should we store so much information on the resource node, or should we denormalize the data in client applications?
The denormalized architecture would look like this: all user data on the resource node, localized user data on each client host. Thus, it user@example.com
will have its own personal information on the resource node and have its own role editor
stored on the client app1
. If he never uses it, he app2
can completely forget about his existence.
The disadvantage of the denormalized model is that there will be a lot of duplication of data (account IDs, roles) and code models ( User
and Role
) on each client , separate management interfaces, etc.).
Are there any disadvantages to keeping the data separate? The client applications are very reliable - we made both of them, but in the future we will probably add additional client applications that are not under our control.
source to share
The most correct way to use oAuth and other similar external authorization methods, as I see it, is strictly for authentication purposes. All business / authorization logic must be constantly handled on your back end and you must always keep a central user record referencing external information for the external auth service type.
Having a tiered / multipart access set is also a must if you want your installation to be scalable and reliable in the future. This is a standard design that is separate from any authorization logic and is always directly dependent on business rules.
Stackoverflow does something like this, suggesting to create a real account on the site after using your external method.
Update: . If the sites are really similar, you can multiply this project with an object for each application that supports specific rules for accessing applications. This object must also inherit from a global object that has global rules (so you can, for example, enforce a ban at the application level or at the enterprise level).
I would use objects that contain acess settings, and roles that can be bound to instances of both application level settings and global settings just to automate / compress access assignments.
In fact, you can use this design even if they don't look too similar. This will help you avoid redundant customizations and meaningless (business-wise) roles. You can define the role only by the name / purpose of the task, and then impose your own restrictions by linking to the corresponding setting of the acess settings.
source to share