May an OAuth 2.0 access token be a JWT? - oauth

From what I can tell, the OAuth 2.0 specification is extremely vague in terms of what form an access token should take:
The token may denote an identifier used to retrieve the authorization
information or may self-contain the authorization information in a verifiable manner (i.e., a token string consisting of some data and a signature). Additional authentication credentials, which are beyond the scope of this specification, may be required in order for the client to use a token.
The access token provides an abstraction layer, replacing different authorization constructs (e.g., username and password) with a single token understood by the resource server. This abstraction enables issuing access tokens more restrictive than the authorization grant used to obtain them, as well as removing the resource server's need to understand a wide range of authentication methods.
Access tokens can have different formats, structures, and methods of utilization (e.g., cryptographic properties) based on the resource server security requirements. Access token attributes and the methods used to access protected resources are beyond the scope of this specification and are defined by companion specifications such as RFC6750.
(emphasis added)
The linked RFC6750 doesn't offer much further specificity. There is an example HTTP response body that shows:
{
"access_token":"mF_9.B5f-4.1JqM",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
}
This seems to indicate that the access_token can be opaque ASCII text such as an encoded JSON Web Token (JWT)
From my perspective, it seems like JWT-as-access_token has some desirable properties:
It's a known specification, with fairly wide adoption and client libraries available in many languages.
It allows for easy signing and verification using vetted cryptographic libraries.
Because it can be decoded to JSON, it would allow us to include metadata and information about the token within the token itself.
My questions are: First, is it permissible for the access token to be a JWT? Second, if it is permissible according to the spec, are there any additional considerations that would make using a JWT as an access token a bad idea?

A1: Using a JWT as an access token is certainly permissible by spec exactly because the spec does not restrict its format.
A2: The idea behind using a JWT as an access token is that it can then be self-contained so that the target can verify the access token and use the associated content without having to go back to the Authorization Server. That is a great property but makes revocation harder. So if your system requires a capability for immediate revocation of access, a JWT is probably not the right choice for an access token (though you can get pretty far by reducing the lifetime of the JWT).

As long as the Authorization Server and the Resource Server agree on what the access token means, it doesn't matter what their content is. So the only reason you could have a problem would be if you were using different libraries or frameworks when implementing those two servers.

Currently the OAuth Working Group is working on a JWT profile for OAuth 2.0 access tokens: JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens

Related

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 Identity server 4 implements Json Web Tokens

I am very confused about the difference between oauth2 tokens and json web tokens.
I have searched about these technologies and the result is ;
Open Id is a protocol and It uses JSON Web tokens to ensure the requests are coming from a trusted user.
A Json web token contains a few user information ( claims ) as encrypted with a private key of sts.
Oauth2 is a framework and we can manage the login operations between our users , clients and resources and third-party applications.
Identity Framework 4 is an Open Id connect implementations .net MVC library. The library has written with oauth2 specs and it implements Open Id.
This is the point I didn't understand. The Oauth2 framework already has its token implementation.
Where is the place of JSON web tokens in this scenario?
For example, we have a simple web application and a server which implements identity server 4.
When a user requested a page from web application user will be redirected to our identity server to login operation.
After successful login Identity server adds a cookie to our response and these cookıe contains a token.
We wıll use that token when requests the other secure resources .
These steps are clear for me. Where is the Jason Web token in this schenio ?
How can I use JSON web tokens in my client app?
Where can I reach my user claims?
The reason for JWT is given in the specs of OAuth2
Since OAuth 2.0 does not define a protocol for the resource server to
learn meta-information about a token that it has received from an
authorization server, several different approaches have been
developed to bridge this gap. These include using structured token
formats such as JWT [RFC7519] or proprietary inter-service
communication mechanisms (such as shared databases and protected
enterprise service buses) that convey token information.
Being an open-standard JWT has been largely adopted in security-related technology and protocols. It defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed
Let's explain some concepts of this definition further.
Compact: Because of their smaller size, JWTs can be sent through a URL, POST parameter, or inside an HTTP header. Additionally, the smaller size means transmission is fast.
Self-contained: The payload contains all the required information about the user, avoiding the need to query the database more than once.
There are a lot of sites explaining these things as well as numerous technology providers.
https://jwt.io/introduction/ for providing tutorials and free e-book
https://oauth.net/2/ for in-depth stuff
https://openid.net/connect/ for the new kid on the block
To answer your IdentityServer related questions. Authentication & authorization related information are usually encoded
access token
identity token
The application-specific information/payload in these tokens is encoded using JWT. JWT is mostly transparent to application developers if good libraries are provided - as is the case for IdentityServer. You will find answers to your questions in the excellent documentation for IdentityServer. How to extract user claims is covered as well. The project provides numerous client examples that cover typical AuthX setups out there. It takes time and commitment to get through it.
JSON Web Token (JWT) (RFC 7519) itself is independent of OAuth 2.0 and OpenID Connect. You can use JWT wherever you like.
OAuth 2.0 is a specification as to how to request and issue access tokens. The specification does not say anything about how access tokens should be represented. Therefore, access tokens may be random strings or may be JWTs. Some authorization server implementations generate random strings and issue them as access tokens, and other implementations generate JWTs and issue them as access tokens. See “7. Access Token” in “Full-Scratch Implementor of OAuth and OpenID Connect Talks About Findings” for further discussion.
OpenID Connect is a specification as to how to request and issue ID tokens. The specification says an ID token is a kind of JWT. In addition, JWT is used in other places in the specification. Responses from UserInfo Endpoint are either plain JSON or JWT. Request Objects are JWT.
In normal cases, a server which supports OpenID Connect can issue both ID tokens (which are JWTs) and access tokens (which are either random strings or JWTs). This may be making you confused. Reading the following articles may be of help.
Diagrams of All The OpenID Connect Flows
Diagrams And Movies Of All The OAuth 2.0 Flows

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.

Specific algorithm in oauth2

I need to realize SSO system using Oauth2.
I understand steps in oauth2, but I don't know what's the Specific algorithm in generating an authorize code or an access_token,maybe Hash or something.And I can't find it on the internet
OAuth 2 specs:
Access tokens can have different formats, structures, and methods of
utilization (e.g., cryptographic properties) based on the resource
server security requirements.
The format of the tokens (and authorization codes) are not defined by the specs, so there is no specific algorithm.
The specs do require:
The authorization server MUST ensure that access tokens cannot be
generated, modified, or guessed to produce valid access tokens by
unauthorized parties.
So, for instance a random UUID makes a fine token. You could also consider JWT tokens.
OAuth2 spec doesn't specify any algorithm or way to generate token value. You can use whatever algorithm, even serial number starts from 1, to generate those token values. You can use more complicated random number generation, encryption, crypto algorithm. Most of them are pretty quick to generate key value, but you need to check how fast current authentication server can generate a key and if it meets your service's requirement.
For example, for token generation in Spring Security, DefaultTokenServices generates access token and refresh token using random UUID.
Unless you want to implement your own Oauth generator, you can use existing providers like WSO2 API Manager for supporting your system. It is well documented and has many REST APIs for this.
access_token contains the claims. So do authentication of user/client and other validations as mentioned in oauth2 spec. Then if you consider JWT for access_token format then you can use jose4j api for access_token creation which supports JWE and JWS as well.
OAuth2 does not define a specific method to generate or protect tokens (authorization code, access/refresh token).
You can implement any strong symmetric cryptographic algorithm, so that you can protect or encrypt the token you are sending.
If you don't want to check token against database you should have this strong encryption.
If it is fine to check token against database you can use a key-value pair, so that you provide key to user and value is stored only in database.

JWT and server side token storage

Every article I've read vouching for the advantages of JWT state that one of these advantages is its ability for an auth system to be distributed across multiple servers. i.e . You aren't relying on a central repository of user auth details to do a lookup on every request.
However when it comes to implementation, I've read in many places that for added security you shouldn't just rely on the JWT signature verification itself, and that you should maintain a list of black or white list tokens generated by the server.
Doesn't this defeat the advantage I've listed above, as this list of tokens would need to be stored centrally where all servers can access it and it would require a lookup on each request?
How have people implemented this on their end?
You are making very good points in your question. Actually it would make sense to store an OAuth token at a central location in order to make it easier to implement signout/revoke functionality. If you just relied on the token signature you couldn't have possibly implemented such feature. Suppose that a user wanted to revoke an access token. In this case if you didn't have a central location/datastore for those tokens where you would have invalidated it and only relied on token signature, then the token would still have been valid.
So indeed, when you want to build more advanced systems that are dependent on OAuth tokens, a central store for those tokens is more than a must.

Resources