OIDC generalized scopes - oauth-2.0

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.

Related

spring oauth2: resource server without authorization server

I need some lights about convenience of using an autheorizarion server in my project scope.
We're realising and deploying our services into customer environment.
Customer infrastructure already provides an authentication mechanism in order to authenticate users.
This mechanism intercepts all comunications and redirects user to a "login" form.
After that, user is redirected to our service and we've to handle and digest it and respond with an JWT token.
Here is where I'm feeling lost:
I'm thinking about:
using spring-oauth2 in order to request a JWT token to an authorization server, or
using spring-oauth2 in order to auto-generate an JWT token and validate it. I don't know if it's possible.
My question is, since user is already authenticated, have it sense to use an oauth2 authorization server, using client-credentials in order to authentication client against our resource services?
Short question would be, could I use spring-oauth2 librearies in order to generate a JWT without an authorization server?
You technically can do it, but I would discourage you from doing that. Access tokens in a system should be issued centrally, by a dedicated service. Otherwise, it will be hard to maintain the infrastructure. If your services will start to issue JWTs, then they will also have to provide the public keys for others to validate these JWTs. Keys management, access token contents management, and any rules of mapping user information into claims - will now become part of your service and it will unnecessarily complicate its implementation.
If the customer's authentication mechanism issues a JWT, why not use that one for request authorization? If that one is insufficient, I would recommend having an Authorization Server (or a dedicated service), that can perform Token Exchange and exchange the original JWT for a new one.

What is the correct grant type for browserless connections like calling a REST API from a server?

I am trying to understand OAuth2 and its grand types. I just want to know what is the propper grant type flow for authorize a browserless application (a job for example) with a REST API.
authorization_code and implicit flow require user interaction (writing the username and password in the browser), hence both are not suitable for browserless authorization.
client_credentials could work, but there is no user in the authorization process, so what happend if the REST API needs to know the user to check for permission/roles/scopes? Maybe creating a client for each user could work, but sound like a bad thing.
passwordgrant type will be deprecated in the OAuth2.1 specification, so this is not an option.
You may thing that OAuth2 is not the framework to use in this case, because you don't need authorization delegation, but what about if you have both (it is so common), a single page application where you could delegate authorization and also a REST API. What is the propper way to authorize a REST API using Oauth2?
Given that this is a background job, Client Credentials Grant is the best OAuth 2.0 related approach. And, it does not use any end user credential (End users and clients are two different entities with respect to OAuth 2.0). Hence you simply need a credential for the given client application.
Other approach is to enable API tokens. But this will require a manual step where you will insert the token to the background job. Again, this is independent from any end users.
p.s - Read about roles (i.e - client vs end-user/resource owner) - OAuth 2.0 roles

OAuth 2.0 flow for user groups / organizations

OAuth 2.0 protocol provides permissions delegation of a user so that third-party apps can operate on its behalf. A typical way this is done on the OAuth flow is requesting a user consent to either approve or deny access for the app (Okta example). Here is an official spec describing how it works in general concepts.
I'm looking for the standardized approach to perform the same flow but for the user groups (e.g. organizations). GitHub does that in some way for organizations, so it looks like organizations represent just a group of user accounts. Are there any standardized approaches to this problem?
If not maybe there are any recommended ways how its typically done architecturally or can fit into OAuth 2.0/OpenID Connect protocols.
The OAuth 2.0/OpenID Connect protocols do not cover how access control is performed.
You can, within the OAuth 2.0/OpenID Connect protocols, pass OAuth Scopes or use the OIDC user info endpoint data to allow the resource server to make determination for Access Control.
Many of the commercial products within this area allow the use of LDAP as a back-end for authentication and will even convert LDAP Groups to Scopes.
I would assume, but I do not know, that GtHub stores data with a link (like a group) for the on Organization and/or the user. I know GitHub exposes this using OAuth Scopes.
Oh, and the OAuth Spec is at: https://oauth.net/2/
But if you require Authentication of users then you need to be using OpenID Connect which is built on-top of OAuth 2.0.
Remember that "OAuth 2.0 is NOT an Authentication protocol"
-jim
There are limits to what you can show on the consent screen and dynamically calculated data is not usually supported.
You ought to be able to express a high level scope that you can present to the user though.
In terms of authorizing based on a user's organisations the claims caching technique here can be useful:
https://authguidance.com/2017/10/03/api-tokens-claims/
That is:
* Use OAuth for user identification and high level checks
" Then do the real Authorization based on your back end data
I'm making some assumptions here, but I believe the issue arises from trying to authenticate two things at once.
If the organization is what you need, then go ahead and create a flow to authenticate the organization as the principal subject (via a user who has access to it), instead of actually authenticating the user itself.
Once the access token is generated, you do not necessarily need to know which user generated it anymore (or at least, the token itself does not need to know). If your user needs to be able to view and/or revoke access tokens, they should still be able to do that, since they have access to the organization in your app.

Client bound access token

Looking at the Oauth2 specification, it says in section 6:
... the refresh token is bound to the client to which it was issued.
However, I can't find anything in the specification the explicitly states that the token should be bound to the requesting client also. I am assuming this to be the case, and the Introspection Extension seems to support that assumption, but I want to know if that is correct.
As an example, say I am using two applications that use Google as the Oauth2 Authorization Server. I'm assuming that Google will issue two different tokens, one to each application, and that the tokens can only be used by the client to which they were issued because they are bound to that client.
An access token can have various implementations. The one that is most widely adopted today is the "Bearer" token, in RFC 6750 https://www.rfc-editor.org/rfc/rfc6750. A Bearer token is not bound to the Client on purpose: it makes it easy to implement, lowers the barrier for adoption and caters for a wide range of use cases.
Assuming that a Bearer token cannot be easily stolen, it is acceptable to avoid binding it to a specific Client: the intended Client could indeed share the access token with another Client but it could just as well share the data that the access token permits access to if the token was bound.
In environments that demand higher security one could use a token that is bound to the Client as defined in RFC 7800 https://www.rfc-editor.org/rfc/rfc7800.
Yes, I think it is implicit in the specification that the access token should only be used by the application that the user authorized. Putting it differently - having something other than the authorized application use the token to access user data is pretty much the definition of a privacy failure, and is what authorization protocols are explicitly designed to prevent in the first place.
Now, in practice, I think that having one application use the access token from another would work fine in many OAuth 2.0 implementations. I don't thing the Token Introspection extension is widely used, and most access tokens are designed to be self-validating. Indeed, that's the reason why token stealing is a security risk. By contrast, the refresh token should only be useful when combined with the client secret, so it's "bound" to the client technically as well as philosophically.

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?

Resources