I'm reading the OAuth2 spec:
https://tools.ietf.org/html/rfc6749#section-4.4.2
Specially the section on client_credentials
grant type.
If the access token request is valid and authorized, the
authorization server issues an access token as described in Section
5.1.
A refresh token SHOULD NOT be included. If the request failed client authentication or is invalid, the authorization server
returns an error response as described in Section 5.2.
An example successful response:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"example_parameter":"example_value"
}
`
I'm somewhat confused why an authorization server can return refresh_tokens for password
grant types but not for client_credentials
.
I'm guessing that it has something to do with the fact that the refresh_token can be exchanged for an access_token and because the client_credentials grant type does not require a username and password, in the event that your application keys and refresh_token is compromised revocation becomes much more difficult?
When using the client credentials grant, the client application authenticates to the authorization server using its client id and client secret. It gets back an access token for the resource if authorized. There's no user interaction in this scenario, so there's no need to issue a refresh token.
When the access token expires, the client can use its own credentials to request a new token. Refresh tokens are used when the client want to access a resource on behalf of the user (which may not be interacting with the client at that time).
In this case, the client is acting on its own behalf.
When applying the Resource Owner Password Credentials grant, it makes sense to return a refresh token so that the client does not need to store or cache the Resource Owner's password - as initially provided by the Resource Owner in an interactive fashion - to get a new access token.
In the Client Credentials flow, the client's credentials are provided from storage anyway - in an off-line fashion - so the refresh token does not gain any security or usability advantage over just re-using the client credentials again (the client has access to those anyway) to get a new access token.
The key part to understand this, is that the refresh
concept is NOT designed for you to refresh a whatever access token you already have.
The "refresh token" is simply a way to skip end user intervention and still regain a new access token, IF your app is using end user username/password authentication, i.e. acting on behalf of a specific end user. (If I were the designer, I might name "refresh token" as "bypass-user-intervention token", so the current question wouldn't need to be asked.)
But if your app is using client credential to authenticate, it is acting on its own behalf, and you don't need user intervention at all, and the server doesn't need to (and won't) give you a refresh token either.