Client Credentials and Password Grant Types


In this video we are taking a look at how the Password and Client Credentials OAuth2 grant types are used with a FOS OAuth Server Bundle installation.

We will be continuing to use the existing Client we created in an earlier tutorial.

We've modified our Client to have an easier to type random_id and secret, setting ours to aaa and bbb respectively.

Our Client has been configured to have all the required grant types to get us through the tutorials, but if following along, be sure your Client has at least got password and client_credentials grant types configured.

For each grant type we cover, we will be removing any created database records so that each grant type explanation starts off that same.

Where possible, we will make use of the Postman app, which is free and amazing and you should definitely be using it if you're working with APIs.

Client Credentials Grant Type

I started the demonstrations with the client_credentials grant type as it is the easiest flow to see in action.

To gain an Access Token we simply need to pass in a valid client_id, client_secret, and of course tell the end-point that this is a grant_type of password.

We will follow the guidance of RFC6749 Section 3.2 guidance, in that we will be making a POST request to our Token end-point.

In the video, our Token end-point is:

http://rest_oauth2.dev/app_dev.php/oauth/v2/token

In the real world, this must be a HTTPS URI.

As soon as we submit, all being well, we will get a JSON response containing our access_token, an expiration timer (expires_in), the token_type which in this case is bearer, and a list of scopes, which will be blank as we aren't covering scope as of yet.

Notice, there is no refresh_token, given in this grant type.

If you are going to receive a refresh_token, you will always get one at the same time as you receive your access_token. However, not to worry if all this is foreign to you at this stage, we'll cover Refresh Token shortly.

As we are not passing in any User credentials, at this stage we would not have our Access Token associated with our User.

This grant type is useful for system to system communications, or situations where the Client is trusted. This is not a good fit for a mobile app.

Password / Resource Owner Credentials Grant Type

The key point to understand with the Password grant type is that the username and password you are passing in relate to a User, whereas you still need to pass in the client_id and client_secret as before.

We also need to pass in the grant_type of password.

We still want to talk to the same Token end-point:

http://rest_oauth2.dev/app_dev.php/oauth/v2/token

If all goes well, this time we receive all the same information as the client_credentials grant type gave us (with only the values being different).

However, this time we also receive our refresh_token.

As we have passed in some valid User credentials, this time our Access Token is associated with the User we gave credentials for.

Likewise, there will be an entry created for our Refresh Token, which will also be assigned to our User.

This is a good choice if you have an API you have developed for yourself or your company and you want to now provide a Mobile App or similar. You trust your user base, you trust your servers, and you control the flow.

Whilst you may be thinking - well, this still exposes the client_id and client_secret, we will cover a way shortly to mask those two via a proxy. That sounds like a lot of extra work, but it is pretty easy honestly, so don't dismiss this flow.

Potential Problems

As shown in the last part of the video, there is a potential problem with issuing access_tokens with the password grant type.

The problem is, if we pass in a valid username and password combo along with a valid client_id and client_secret, this grant type will not actually check to see if this User should be allowed to get an Access Token for this Client.

As you will see in the video, our second User - Bob - has no relationship defined in our fos_user__to__oauth_clients table.

But a request for a token is still granted, and both the access_token and refresh_token are assigned to Bob.

This can be mitigated later in the work flow, but it can be confusing and for me at least, isn't the expected behaviour.

Code For This Course

Get the code for this course.

Episodes