Oauth2, client_credentials, and scope - oauth-2.0

I've been using Oauth2 for quite some time as a developer but still feel at times I need to go back to the basics. I have a general question around this topic, specifically when it comes to using scopes.
As I understand, scopes are a kind of filter that can be applied to certain APIs and the bearer token is required to possess any scope the API requires. In that sense, they offer an extra 'layer' of protection after the token itself. However, what I would like some feedback on is how best to protect an API that requires scopes. If a consumer obtains a valid bearer token from the issuer and discovers what scope is required for a service, what's the best way to prevent them from making a POST using a token obtained through client_credentials, for example, on a restricted resource?
I believe I know a few solutions: require some sort of user token as well and further lock down resources via a authorization in your business logic (e.g. customers can only modify their own data). Another option might be to require api registration and an approval workflow so only 'approved' clients can invoke a service. Similar to how Akana and other API Gateway products operate. But are there other things I'm missing? Are Scopes really meant to serve as an authorization mechanism at all, or am I misinterpreting their real purpose, because to me they don't seem like they offer much.
Thanks for feedback in advance.

Related

Need some conceptual guidance of scope vs roles

I'm trying to wrap my head around scopes for this scenario.
I have a SPA client and an API. The client only communicates with this API and the API has no other clients communicating with it.
The application has two access levels, say a user and an admin (the SPA may block some routes for the user and the API may block some endpoints).
The roles are administered with AD-groups and mapped to the roles claim.
So what role does scopes play in this scenario? I do all authorization based on the roles claim. But I still need to specify a scope, so I have a API://[clientid]/all scope. Could someone help me make sense of all this?
Scopes are fixed at design time. They are high level privileges that indicate an area of data and what you can do with that data. These are often used as sanity checks, eg to prevent tokens for a valid user but wrong app being used to call an API.
orders_read
Claims are dynamic values looked up at runtime, and tend to have different values for different users. Pretty much all real world authorization is based on claims:
role = supervisor
company_id = 407
So in your case just define a scope or two, but keep them high level and easy to manage. Your claims based authorization (using roles) seems fine.
FURTHER INFO
At Curity we have a couple of good docs that explain the science of designing authorization based on OAuth standards:
Scope Best Practices
Claims Best Practices

OIDC generalized scopes

Currently building up a microservice for handling auth-related stuff using OIDC.
Now, we think about access control and how to be as future-proof as possible. This auth server is only used for first-party applications (3x SPA, 2x native mobile App). On mobile, we use the authorization_code grant. Each resource server validates the supplied token (access token as JWT) itself. But what happens when (in future), we add a service which needs its own scope to check (e.g. notifications:read)? As mobile app users are not used to logging in and out everytime (when we would update the requested scopes via an app update -> bad solution) is there any sweet solution to manage this scenario?
Per specification, it's possible to change the required scopes when refreshing a token but this is limited to require less scopes than originally requested and not more so that's not an option.
For example, Facebook is providing only four scopes for Instagram e.g. instagram_basic or instagram_content_publish. Zalando for example includes only a scope NORMAL_USER in their tokens whereas Wolt includes the users roles as a claim.
I think there is some confusion as this scenario is not covered directly by OAuth2 or OIDC. What are your thoughts about this?
There is one standard for doing OAuth 2.0 Incremental Authorization, but your challenge is to find a token provider that supports it or similar standards.
In a micro service architecture, the question is if you should use the access token from the authorization code flow everywhere, or if for service-to-service communication, you should use client credentials flow instead.
See also https://www.gmass.co/blog/oauth-incremental-authorization-is-useless/
It seems like you could use Token Exchange for that.
For example it could work like that - whenever your resource server gets a token without the notifications:read scope, issued before date x (so before you were issuing that scope) it performs an exchange with the authorization server and (if the server decides that it can perform the exchange) it gets a new access token that contains that scope. If the token was issued after date x you can safely assume that the token was not granted this scope.
Another solution would be to use claims for authorization decisions instead of scopes. The authorization server can issue e.g. a claim notifications_read: true, or something like that. Whenever you refresh tokens you can issue more claims in the new access token, the spec does not prevent that. Then your resource servers should check claims in the access token, they can ignore scopes. The resource server would just check whether the token contains the notifications_read claim with value true, or not. This solution gets a bit more complicated if you require your users to give consent to scopes, but as you said you're using this only for 1st-party, so I assume you're not using consent screens.
You can have a look at this free course - this topic of using claims in authorization is covered in part 4.

How should scopes be defined for an API ecosystem with OAuth?

As the creator of an API ecosystem with OAuth, you want to allow access to your APIs via scopes that can be attached to an access token. My questions are thus:
How do YOU define a scope?
Would you expect any scopes you define to provide access only to resources/methods within a single API, or should a scope include access across multiple APIs?
How likely are you to define scopes in an API definition file like Swagger/OAS or RAML vs. within some sort of API gateway tool?
Should scopes be defined outside of the context of a specific API as part of a separate OAuth management tool, alongside things like IdP registration and client application creation?
I realize there may be several possible answers and perspectives on this - that is exactly what I am looking for.
Thanks for your help!
My OAuth2 server has the ability to create arbitrary scopes. Scopes are similar to 'roles', they describe groups of functionality.
The OAuth2 server is essentially unaware of what theses scopes are. API Resource servers receive Bearer tokens, and based on the bearer tokens find out what scopes are associated with it, and make decisions on what a user can and cannot do with that scope, but to the OAuth2 server, they are opaque strings.
We don't use swagger/RAML.

OpenId Connect - 2 way exchange of tokens in spec?

Does OpenId support a two way exchange of tokens at any place in the spec? Specifically allowing both parties to share tokens with each other in some way so they can share services with each other?
I've looked through the spec, but can't see anything detailing any scenarios like this.
An app I'm working on has integrated itself with a trusted OpenId provider, we'll call Acme.
We'd also like to provide access tokens and refresh tokens to Acme, as they'd like to access features of our service as well.
It seems natural that during our interactions to get tokens from Acme, that we'd like to expose tokens to them.
Is this part of the spec in any way? Or is the only way to do this is to become a full identity provider ourselves?
You could include the tokens as part of a request object, see: http://openid.net/specs/openid-connect-core-1_0.html#RequestObject but that would depend on a pair-wise agreement with Acme since they'd need to handle the non-standaridzed request object contents.
The best way forward is to become a provider yourself so you can leverage all the features of the various flows without being dependent on a pair-wise agreement and accompanying implementation.
It sounds like you're confusing OpenID Connect and plain OAuth2 to some extent.
OpenID Connect is a specification for identifying end users to a client application, based on their authentication at the OpenID Provider. It's not clear from your question whether end users are even part of the picture, so even plain OAuth2 may not be relevant (unless you are just using the "client credentials" grant).
Neither spec says anything about mutual exchange of tokens. It would probably help if you describe the interactions you anticipate in more detail and which grants you expect to use. Who will authenticate to your identity provider and what would be a typical client application?

OAuth: what information should I store in tokens

I am creating an OAuth server which issues tokens to users. However, I don't want to store tokens in the database, and I want the processing to be fast.
What I'm thinking is to include various information in the token, so that when I decrypt it, the information is already enough to check for permissions and scopes.
I'm a little worried about the token's length growing as I add more scopes.
Is this a good idea? If not, what can you recommend?
What you are talking here is about InMemoryTokenStore which is the default implementation. Also Oauth2 already maintains the information required to check permissions and scopes in token in form of different access roles provided by authorization server to various clients. I think you don't need to explicitly store anything in token.

Resources