OAuth 2 - how to define dynamic resource authorization? - oauth-2.0

As a resource server, I'd like to give users more control over their resources.
For example, consider I have a cloud file system supporting OAuth 2.
The user may provide permission to access the files to a client on his behalf.
I'd like the resource server to offer access to specific folder, for example, just photos and not documents.
The names of the folders is a dynamic resource, as it varies among users.
How can I handle dynamic resource authorization? Dynamic scopes?
Also, if the scope is dynamic, how does the client know to request it?
* Couldn't find it in the spec :(

The document rfc6749 which is the OAuth 2.0 spec, defines a way to extend OAuth 2 by using additional parameters(rfc6749#section-8.2).
So, if you want to solve this with OAuth, you could use this approach or something similar:
you define a new parameter for the Authorization Request to specify a resource(EX: folderID=XXXXX)
During the Authorization request, a client can OPTIONALLY specify a resource by using the new parameter
If the parameter is specified, your Authorization Server will generate a "dynamic scope" which must be signed by the Resource Owner
if the parameter is not specified, the Resource Owner can select the resource he wants to share, and the Authorization server can generate the related "dynamic scope" (This scenario implies that the resource server is involved somehow during the Authorization flow)
When the scopes are defined and signed by the Resource owner they are communicated to the Client (it should be able to derive the resource ID from the scope if the latter has been defined by Resource Owner)
When the Client asks for a resource, the resource server also has to make sure that the scope includes the requested resource
Bear in Mind that such approach works better if the amount of resources per user is not very big (otherwise you can be flooded of scopes).
Another method could be to add an extra layer of Authorization behind the OAuth Layer. This additional layer keeps track of the relation client/accessible resources.

Just recently I had to familiarize myself with OAuth/OIDC, and now I am facing the same question - here's what I could think of so far -
You surely have a reason to externalize security (authN, authZ) - that's why you use OAuth. Do you really want your Authorization Server to know about the resources you have in your application?
Scopes - as far as I understood - control access to APIs, not 'resources' in the standard meaning - even though I read about 'resource' typed scopes, but those were again giving access to an API.
If you have resources (files) you want to control access to, you'll probably better off handling it inside your application - and optionally request the list of known clients from the Auth Server, if you have to.
This is the way I am going to try doing it for my own app anyway - it is indeed surprising not to find any resources about this online.

Resurrecting a pretty old question here, but I think the problem is still current.
One useful detail to bear in mind is that the scope requested by the client and the scope allowed by the Resource Owner don't have to be equal. In fact, the scope allowed by the RO doesn't even have to be a subset of the requested scope.
In your case, the scope allowed by the RO can be a set of resource URLs, selected by the RO at grant step depending on the requested scope. Then, by looking at the values in the access token and understanding their meaning, the Resource Server will be able to serve the requested resources dynamically.

Related

Identity Server - Multiple users with different access levels on different accounts

My application is composed of an API layer which is accessable by presenting a Bearer Token, obtained from our Identity Server. Each of our API has a level of scopes that the token must contain in order to be invoked: this means, for example, that if you want to make the API call which "creates a product" you need a write access to products (i.e. the scope "products") while you may just need the scope "products_read" if you only want to retrieve them.
Scopes are bound into the token when you authenticate onto the ID server.
Now, I need this user to be able to perform different operations on different "workspaces". Each workspace administrator can set which permissions each user have. This is, in fact, linked to the scopes that each user will have when operating on that particular workspace.
Right now we have implemented that, if you are trying to access a different workspace, the API layer will check:
if your bearer token is valid (by validating it on the ID server)
if you are authorized to access that workspace
changing associated claims by removing the original "scopes" (set into the token by the ID server) and overwriting with those assigned by the administrator of that workspace
This somehow works, but it stinks because I don't want my application layer (API) to have this kind of responsability and the opportunity to tamper with the token. I want the ID server to handle it and, after the user tries to enter into a different workspace, it generates a new crafted bearer token with correct claims (so the API will just need to trust it).
What's the best approach in doing that? I'm digging into the "custom grant type": may this be the right approach?
Scopes are fixed at design time and the same for all users. I like your use of products and products_read - that is very standard.
When you need dynamic behaviour, implement claims, which depend on who the user is. In your case I would use a workspaces array claim. Since this is a key vaue for authorization, it should be added to access tokens at the time of token issuance. Think in terms of your products scope being composed of claims.
It feels like workspaces and other permissions are part of your business data rather than your identity data. At the time of token issuance, IdentityServer should send identity attributes (eg subject claim) to an API endpoint you provide. which returns business attributes (workspaces). I believe in IdentityServer this is done via a custom profile service.
I'd try to avoid different tokens for different workspaces, since that will be awkward in terms of usability and code complexity. The standard way to do it would be to redirect the user each time.

What are the pros and cons of "super" access tokens with large numbers of scopes?

Context
We use Identity Server for identity and access control in our solution. Our scope names have the form of URLs so they are 40-60 characters long.
Some time ago we received a request to increase the max length for scopes in the request. The default value is set to 300 in InputLengthRestrictions class and it can be changed very easily. However, after some discussions, it turned out that for now it may be enough to increase the max value to 500 or 1000 but in the future, an even bigger limit may be needed in order to be able to request 10, 20 or more scopes.
Here comes the question. Is it a good practice to request an access token with such a large number of scopes? What are the pros and cons?
My thoughts
From my perspective, the main benefit of having one "super" access token has one main advantage i.e. it is convenient because it allows you to call all APIs.
On the other hand, I see some drawbacks and/or code smells:
The fact that a large number of scopes must be requested may mean
that scopes are too granular.
The fact that a large number of scopes must be requested may also suggest that scopes are used more as permissions. It is especially a problem in the case of long-lived tokens as they cannot be revoked easily.
Requesting a large number of scopes may suggest that you request
more than you actually need. However, it is recommended to "choose the most restrictive scopes possible".
Having a super access tokens expose a higher security risk if such a token is intercepted.
In implicit flow, a token is passed in URL so the large super token can exceed the maximum length of the URL.
Super tokens might be too big to store them in cookies (it is a
different topic if tokens should be stored in cookies).
Super tokens can be quite large so the network performance can be affected.
What do you think? Do you see any other pros/cons of super tokens? I'm not sure but maybe large super tokens can affect Identiy Server performance.
I don't have pros or cons for you, but perhaps this answer can help you.
Looking at IdentityServer you'll see three parts, the resource, the client and the user. IdentityServer has two main responsibilities, authorize the client and authenticate the user. User authorization is actually not the responsibility of IdentityServer. That's why they created PolicyServer.
Consider the following resource:
resource = CalendarApi
scope = Calendar.Read
scope = Calendar.Write
scope = Calendar.Event.Create
The resource is just a logical name. It can consist of one or seperate api's (as in projects), where an api can implement a single or multiple scopes. In the api a scope is an implementation of certain functionality.
Only a client can request a scope, because the client knows how to use the functionality.
Suppose I have two clients: Mvc1 and Mvc2. Mvc1 has a calender view and an admin page, while Mvc2 only shows the calendar.
My configuration:
Mvc1: scope = Calendar.Read Calendar.Write Calendar.Event.Create
Mvc2: scope = Calendar.Read
It has no use for Mvc2 to request all scopes, because it doesn't use the other functionality. It wouldn't make sense to request all scopes. And in case Mvc2 is a third party app, you shouldn't, because they could use it even when this was not the purpose.
Best practice here would be that a client only requests scopes that are allowed (as configured in IdentityServer) and may be implemented by the client.
So far the user was not involved, because there is no relation between scopes and users. However, the client needs the user (as resource owner) to actually access the resource.
It then comes to user authorization to determine whether the user can create events on the calendar. This 'permission' is not the scope.
The scope Calendar.Event.Create doesn't allow the user to create an event. It only allows the client to connect to the resource.
When combining the clients and users, then there is only one situation where a user can create an event: when a user with create permission uses the admin page in Mvc1.
Mvc2 can't access the resource, not even when the user has create permission.
Now getting to your question:
Is it a good practice to request an access token with such a large
number of scopes?
The access token should only contain the scopes that are needed, as described above. Only necessary scopes should be requested by the client.
Agree. The number of scopes should not be too detailed. Don't treat scopes as permissions, e.g. create, edit, read. Though I did as example, a better scope would be Calendar, where the user permissions define what the user is allowed to do (CRUD permissions).
Agree, should be investigated.
I would say yes, as argumented above.
It is still the user that has to be authorized. But you should limit the possibility for clients to use functionality that was not meant for that client.
/ 6. / 7. Hitting limits is a good indication that the architecture may need some redesign. In general you should not expose more than necessary and you should avoid hitting limits.
I suspect the problem is that scopes are used as permissions. Remove the 'CRUD' from the scopes and redesign user authorization. Don't set permissions in claims.
In my design there is no need for a super token, nor will I ever hit a limit. There are only few scopes, the access token only contains the sub claim and policy server tells me what the user is allowed to do.
I hope this helps you in any way. Please let me know if something is not clear.
You can implement Service Account flow for same. Using it you can get token of respective client with all allowed scopes to client.
By this way your token does not have included all scope but has scope allowed to client.
I don't have sample code right now but you can check how service account can be implemented

Queries Regarding OAuth2

A simple scenario I have a typical architecture a client,authorization server(OAuth Server) and Resource Server.Client gets token from authorization server with client_credentials and sends token to resource server and it serves the request.So if I have 2 API's either the logged in user can access all or none based on valid or invalid token.
Is there a mechanism to grant access to 1 API ? The question is can token be API specific like it give access to 1 API and not the other.
The scope mechanism can be used to differentiate between permissions that are associated with the access token. E.g. there could be a scope for API A and one for API B. The client could ask for one of those scopes or both and the token would be valid for respectively calling both APIs or just one of them.
See also: https://www.rfc-editor.org/rfc/rfc6749#section-3.3 which doesn't say much about the semantics of scope but in practice a scope is almost always associated with a (set of) permission(s).

Understanding Claims

I'm trying to get up to speed with OpenId Connect, OAuth2.0, Security Token Service and Claims. Imagine a scenario with a large website with many areas and different functionality e.g. Customer, Order, Supplier, Delivery, Returns etc. My question is this – would I create Claims on the Token Server such as CanCreateCustomer, CanReadCustomer, CanUpdateCustomer, CanDeleteCustomer etc, i.e. effectively CRUD Claims for each main area/Business Object? This would lead to many tens but more likely hundreds of Claims. Or is my understanding coming up short?
So fixing terminology, you mean "scopes", not "claims". Scopes are identifiers used to specify what access privileges are being requested. Claims are name/value pairs that contain information about a user.
So an example of a good scope would be "read_only". Whilst an example of a claim would be "email": "john.smith#example.com".
You can send claims in the id token (or JWT), or/and have them available via the userinfo endpoint (if using the "openid" scope).
You can break scopes down per service, and have them as granule as you would like. Or have them as high level (read / write / admin). I would recommend having enough scopes to actively achieve the security principle of least privilege (basically: giving people what they need to do their job). You can use namespaces if you have a lot of scopes.
Your understanding is right, but you have a lot more flexibility in OAuth2.0 scopes (claims)
These scopes can be configured in any way for eg, in your case instead of creating individual scopes for each CRUD operation for each main area, you could create group scopes like
customer.read_write
order.read_write
Etc, you can even go one level higher , by creating functionality level scopes, like
webportal.full_access
adminportal.full_access
Then in your application, after authentication, the authorisation can be done like,
ValidScopesIn({Scopes.WEBPORTAL_FULL_ACCESS, Scopes.CUSTOMER_READ_WRITE})
public void createCustomer(Customer customer) {
// your creation logic
}
I think your understanding is largely correct. However, if I understand what you describe correctly it seems more of an authorization (OAuth) rather than an authentication (OIDC) problem, and as such you might have a look at how other OAuth resource providers define their scopes (not claims btw), for instance GitHub or Slack.
I would recommended that "scopes" be configured as URIs so that collisions do not occur.
As an example.
-jim

How to restrict the allowable permission-set for the OAuth 'scope' parameter (restricting scope)

I want to use Facebook as an authentication source for my application (a website) users. I do not want my application to have anything but basic and email permissions. Thus, my application must not be able to publish to a user's wall for example. In other words, I want to restrict the allowable set of values for the scope parameter and I want this restriction to occur on the application's configuration pages (on the Facebook site itself).
Normally this would be easy, just specify 'email' for the scope parameter of the OAuth URL/call.
However in this case there is another factor and this is: a hacker may gain access to the app and change the OAuth call to specify more permissions. Then an unsuspecting user will typically (or at least possibly) grant those permissions and the hacker will be able to grab the OAuth token and perform actions on behalf of that user.
I'm not interested in discussing the whys of this issue, just in finding of there is a way to specify that my application can only use a specific set of values for the scope parameter. Ideally this specification of the scope restriction be done in the application configuration page on Facebook itself.
However, I am interested in alternate solutions that involve using SAML, OpenID or some other authentication only mechanism (even if I cannot get the users email address). I'm not interested in using RPX.
Please note: this is a complex question not a simple one. I have searched far and wide for an answer and have just found what amounts to the opposite of this question.
I'm pretty sure it's not possible to restrict the scope at application configuration level.
I'd say the tidiest workaround would be to query the permissions of a user on signup, check that they match the allowed permissions, and subscribe to the (permissions realtime updates)[http://developers.facebook.com/docs/reference/api/realtime/]. Your app will be notified of any changes in permissions granted to users.
This should allow you to block any server side API calls through application logic, or (ban)[https://developers.facebook.com/docs/reference/api/application/#banned] a user which escalates permissions.

Resources