8

In a web application which authenticates its users via an IdP using oauth2, what are the more standard/recommended options for implementing user permissions (both client and server side)?

By "user permissions" I am referring to actions that the user is or isn't allowed to perform inside the application.
For example, let's say the application has an "admin" page which is used for managing some of the application's settings, that only specific users are allowed to enter. Some of these users are only allowed to view the current settings, while others are also permitted to change the settings (possibly only some of them).

From what I gather, the concept of "scopes" in oauth2 could probably be used for implementing such a requirement, so for example, a user that is only permitted to view the "admin" page would have a app:admin:view scope, whereas a user who can also edit a setting would, in addition, have a app:admin:some-setting:edit scope.
But, it seems that in most large identity provider services, the task of managing these scopes and their assignment to users would be quite a tedious one.

Would that be a good solution? If so, are there any products/services which integrate with oauth2 IdPs and help managing permissions and their assignment to users more easily (say, with a nice intuitive UI)? If not, are there any established methods handling such scenarios?

jmrah
  • 5,715
  • 3
  • 30
  • 37
Johan Hirsch
  • 557
  • 4
  • 21

2 Answers2

10

Scopes

I would not use OAuth2 scopes for this purpose. The reason is that OAuth2 scopes are for restricting what an application can do with a user's resource, not for restricting what a user can do in the application.

For example, if I wrote a web application that showed users what languages they used in their Google Docs, it would need the privilege delegated from Google to read the user's Google Docs, but not to, for example, read their calendar. So the application would get an OAuth2 token from Google that was scoped with the read-Docs privilege, but not the read-calendar privilege or any other unnecessary privileges.

The concrete drawback of using scopes to carry info about user permissions (as opposed to application permissions) would be, if you want to implement something like the above, where applications get varying levels of access to users' resources within your application, it could be confusing trying to use OAuth2 scopes in multiple ways simultaneously. This could become a problem if you want to expose functionality within your application via an API to your customers to integrate into their own applications.

OAuth2 delegation versus OpenID Connect authentication

You mentioned you are using OAuth2 for authentication. OAuth2 is for delegating authorization, not for authentication. OAuth2 access tokens do not represent authenticated users. OpenId Connect ID tokens do.

AWS Cognito User Groups

I like using AWS Cognito for authentication. It keeps track of your users for you, so you don't need a user database, and handles authenticating them. It integrates with external identity providers like Google and Facebook. For your use case of keeping track of different kinds of users, you can use Cognito Groups. Here is a blog post with an example.

Basically you'll get an ID token from Cognito, and your client or your server can read the ID token to figure out the user's groups (admin, regular-user, etc), and act accordingly. Here is an example of reading the group from the token.

Doug Naphas
  • 380
  • 2
  • 8
3

The authorization server in a OAuth2 implementation returns a JWT (as access token). You can have the authorization server return the user access information in some custom "claims". Spring Security OAuth2 supports this. A tutorial is here.

However, if the users have a long list of access information making the JWT size more than 4KB, you won't be able to store the tokens in a cookie (which is usually used and considered as a secure option to store the tokens on the client side as I explained in my other answers here and here). In such cases you can have a separate microservice that would return the user access information given a user name and you can cache that information locally in your other services.

Saptarshi Basu
  • 8,640
  • 4
  • 39
  • 58