OAuth Client Credential Flow - Refresh Tokens - oauth-2.0

The Scenario
I've recently built an API, and have protected its resources using OAuth Bearer Access Tokens.
I've used the Client_Credentials Flow, as it will be accessed by clients as opposed to users.
Here's the thing, when a client has successfully provided the client_id and the client_secret they receive a response like the following :-
{
"access_token": "<Access Token>",
"token_type": "bearer",
"expires_in": 1199,
"refresh_token": "<Refresh Token>"
}
Refresh Tokens.
Not knowing much about refresh tokens, i immediately assumed that a client would be able to provide the OAuth Server the refresh_token to retrieve a fresh Access_Token.
This is 'kind of' correct.
In order to use the refresh_token the client still needs to pass the client_id and client_secret along with the refresh_token to get a new access token.
The grant_type also needs to be changed to refresh_token.
Where is the benefit of a refresh_token using this flow? If I need to pass the client_id and client_secret each time, surely you would just avoid using a refresh token altogether?

The issuance of a refresh token with the client credential grant has no benefit.
That is why the RFC6749 section 4.4.3 indicates A refresh token SHOULD NOT be included. Thus its issuance is at the discretion of the authorization server.
From my point of view an authorization server should never issue a refresh token with the client credentials grant as the access token issuance process will take an additional and unnecessary step:
The issuance of he access token with the client_credentials grant type is done on the first request.
The issuance of he access token with the refresh_token grant type is done after at least two requests, depending on the way you issued to first access token.

The benefit is that he request token normally has a much longer life span than the access token.
Access token is used in communicating with the resource server.
Request token is used when communicating with the authorization server.
You could read this as that you may be authorized but that the exact extend of your authorization needs to be reevaluated from time to time. So request token has it use.

Related

OIDC standard response if grant_type of refresh_token

Currently I am using /token endpoint to obtain an access token, an ID token (by including the openid+offline_access scope), and a refresh token for the Authorization Code flow. The value for code is the authorization code that I receive in the response from the request to the /authorize endpoint.
Also to refresh access token as well as an ID token, I am sending a token request with a grant_type of refresh_token.
Below is the reference link, I am trying similar to implement in my custom OIDC application.
https://developer.okta.com/docs/guides/refresh-tokens/main/#renew-access-and-id-tokens-with-spas
Does it suppose to return both refresh_token and id_token OR both are optional if grant_type=refresh_token (also in token endpoint openid+offline_access scope added) in OpenID Connect concept?
Below is the link I am trying to understand.
https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens
When you use the refresh token, the purpose is to get a new access token. Optionally, depending on the backend configuration, you might get a new refresh token as well (if you use a one-time refresh token setup).
You never get a new ID-token back, the ID token is usually a very short-lived token (like 5 minutes) and its main purpose is to describe how the user is authenticated and who it is. The main purpose of the ID token is to create the local session (typically a session cookie), after that the ID token has no real use.

Why RefreshToken received form azure active directory is not in JWT format

I need to understand why refresh token issued by AAD is not in JWT format( i used Auth Code grant type for generation of refresh token). It looks something like as follows 0.ATYAoWHs1YRqUk-OAYpDkwKjaYAEJhrbDpBNmWw7q0NZVas2APk....(rest of the token).
Also if we can get this refresh token in JWT format then how can we do that.
Thanks
Abhishek
It isn't in JWT format because it does not need to be.
A refresh token is data that you send to the identity provider to get new access tokens.
It should not have any other meaning for your application.
Store it securely and send it to AAD when you need new tokens.
Then take the new refresh token you get in the response and overwrite your previous refresh token with that.
The OAuth 2 RFC also talks about it https://www.rfc-editor.org/rfc/rfc6749#page-10:
A refresh token is a string representing the authorization granted to the client by the resource owner. The string is usually opaque to the client. The token denotes an identifier used to retrieve the authorization information. Unlike access tokens, refresh tokens are intended for use only with authorization servers and are never sent to resource servers.

Access Token if stolen, can access resources from the service it is provided. how OAuth prevent it other than making it short interval expiration

I am new to OAuth2, was thinking about the scenario where Access Token if stolen, can access resources from the service it is provided. how OAuth2 prevent it other than making it short interval expiration for access JWT Token.
It can't really, if the token is a simple bearer token. As described in the spec, the client could be made to authenticate when using an access token:
Additional authentication credentials, which are beyond
the scope of this specification, may be required in order for the
client to use a token
but that isn't usually done in practice.p
The token doesn't have to be a JWT - depending on the implementation, it's possible that a token revocation mechanism may also be in place which could be used if it was known that a token was stolen.
Tokens should be protected and only sent over HTTPS (a requirement of the spec).

Clarification on id_token vs access_token

I'm building a system with OIDC and OAuth 2.0 (using Auth0), and I'm unsure how to properly use the id_token and access_token. Or rather, I'm confused about which roles to assign to the various services in my setup.
I have a fully static frontend-application (single-page app, HTML + JS, no backend) that ensures that the user is authenticated using the implicit flow against Auth0. The frontend-application then fetches data from an API that I am also building.
Now, which is right?
The frontend SPA is the OAuth client application
My API service is an OAuth resource server
...or:
The frontend and my API service are both the client application
If both my frontend and backend API can be considered to be the client, I see no real harm in using the id_token as the bearer token on requests from my frontend to my backend - this is appealing because then I can simply verify the signed token on the backend, and I have all the information about the user that I need. However, if my API is considered a resource server, I should probably use the access_token, but then I have to connect to Auth0's servers on every API request to both verify the token, and get basic user info, won't I?
I've read this which seems to suggest that the access_token is the only valid token for use with my API. But like I said, I'm not sure about the roles of the individual services. And using the id_token is tempting, because it requires no network connections on the backend, and contains information I need to extract the right data.
What is the right way to go about this?
I like this Medium post about the difference, all cred to this author.
https://medium.com/#nilasini/id-token-vs-access-token-17e7dd622084
If you are using Azure AD B2C like I am you can read more here:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/openid-connect
ID Token
You will get id token if you are using scope as openid. Id token is specific to openid scope. With openid scope you can get both id token and access token.
The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be Authenticated is the ID Token data structure. The ID Token is a security token that contains Claims(claims are name/value pairs that contain information about a user) about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims. The ID Token is represented as a JSON Web Token (JWT)
{
"iss": "https://server.example.com",
"sub": "24400320",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"auth_time": 1311280969,
"acr": "urn:mace:incommon:iap:silver"
}
The above is default JWT claims, in addition to that, if you requested claims from service provider then you will get those as well.
An id_token is a JWT, per the OIDC Specification. This means that:
identity information about the user is encoded right into the token
and
the token can be definitively verified to prove that it hasn't been
tampered with.
There's a set of rules in the specification for validating an id_token. Among the claims encoded in the id_token is an expiration (exp), which must be honored as part of the validation process. Additionally, the signature section of JWT is used in concert with a key to validate that the entire JWT has not been tampered with in any way.
Access Tokens
Access tokens are used as bearer tokens. A bearer token means that the bearer (who hold the access token) can access authorized resources without further identification. Because of this, it's important that bearer tokens are protected. If I can somehow get ahold of and "bear" your access token, I can pretend as you.
These tokens usually have a short lifespan (dictated by its expiration) for improved security. That is, when the access token expires, the user must authenticate again to get a new access token limiting the exposure of the fact that it's a bearer token.
Although not mandated by the OIDC spec, Okta uses JWTs for access tokens as (among other things) the expiration is built right into the token.
OIDC specifies a /userinfo endpoint that returns identity information and must be protected. Presenting the access token makes the endpoint accessible.
http://openid.net/specs/openid-connect-core-1_0.html
https://connect2id.com/learn/openid-connect#cool-id-token-uses
https://developer.okta.com/blog/2017/07/25/oidc-primer-part-1
Your frontent is your OAuth client application, once it stores the token it can take actions on the OAuth flow. And your API service is resource server, because it accepts the access_token issued by your identity server.
Also I would say that your id_token stands for the identification of the logged user and may contain sensitive data for your app. The access_token is standing as your credential to access a resource.
At the end you will use an access_token to request a resource, and then if you need specific data from the logged in user (resource owner), you may request the ID token from the token endpoint.
In my opinion, the first approach is correct. Your SPA is the client application and your APIs are resource servers.
I would suggest you limit the use of id_token till your SPA only. You can use the basic information present in the id token (like username and email) to display user information within your UI. If you can generate access tokens as JWTs too then your API can validate the access tokens without going to the Identity provider. You can include roles (or similar) in your access token to get authorization information in your access token.
I was also wondering if I need to talk to the IdP on every request if I'm using the tokens received from the IdP. I ended up with the following setup:
Only the backend talks to the IdP, the frontend does not.
Upon the IdP callback the backend issues a JWT for the frontend.
User session and frontend-backend communication is managed entirely by my app using the JWT token.
Check this article: OAuth2 in NestJS for Social Login (Google, Facebook, Twitter, etc)
and this repo: https://github.com/thisismydesign/nestjs-starter
and this question: OAuth2 flow in full-stack NestJS application
The id_token is an cryptographically encoded token for authentication. The OP (the auth provider) is the one that generates it and the RP (relying party or the resource) will eventually re-present the token to the OP to counter validate when handed over by the client. In short the id_token is tied to authn workflow.
The access_token enables resource access. It does subsume the userinfo i.e., the id_token or any other principal on whose behalf the access is being requested. So this token includes both user claims plus claims to groups that are authorized. In short the access_token is tied to your authz workflow.

Why Google OAuth2 needs client secret and refresh token to get access token?

After reading the Google OAuth2 documents, I have downloaded the application_default_credentials.json and used this to get access token(bearer token).
I'm not sure if this's the standard of OAuth2. Some documents show that we need refresh token and client credential to get access token, but why not just refresh token? If I have client credential, does that mean I can get access token directly?
Yes, it is part of the OAuth2 specification that you must send the client credentials along with the refresh token. From RFC 6749, section 6:
Because refresh tokens are typically long-lasting credentials used to request additional access tokens, the refresh token is bound to the client to which it was issued. If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server.

Resources