Most of the OAuth flows are for handling delegated authorization, when a resource owner grants access to an application to access her data. However, there are cases when the client itself owns the data and does not need delegated access from a resource owner, or delegated access has already been granted to the application outside of a typical OAuth flow.
This flow (shown in Figure 5-1) works well for similar use cases as the “2-legged” flow in OAuth 1.0.
Imagine a storage API, such as Google Storage or Amazon S3. You’re building an application that has resources (data files, images, etc.) stored externally to your app using one of these APIs. The application needs to read and update these resources, but acting on behalf of the app itself rather than on behalf of any individual user. This is a perfect use case for the Client Credentials flow. The application can ask the OAuth authorization server for an access token directly, without the involvement of any end user.
There is another representative case for the Client Credentials flow—when a resource owner has granted an application access to their resources out of band, without using a typical OAuth flow. Google provides a concrete use case in the Google Apps Marketplace. When an application is listed on the Marketplace, vendors get credentials that represent their application and also register the scopes of data they need access to. When the application is later installed by an organization’s IT administrator, Google asks the administrator whether it’s OK to grant the application access to his organization’s data. When access is approved, Google stores that organization “Acme Corp” has granted access to “Google Calendar and Google Contacts” for application “Task Manager Pro.” Google does not issue any tokens to the application. When the application tries to access data in the future, Google simply looks up whether the application is allowed access to data for the particular organization.
While the preceding paragraphs describe some potential use cases for this flow, these providers (Google and Amazon) have not yet implemented the Client Credentials flow in OAuth 2.0. However, Facebook has implemented this flow for its applications, to be able to perform App Login. App Login is required for certain Facebook API calls, including the ability to get app statistics and user demographics from the App Insights service.
This flow is reliant upon the client being able to properly
authenticate with the authorization server and the client’s authentication
credentials remaining confidential. In order to authenticate, the client
can pass the client_id
and client_secret
to the authorization server as
POST
parameters in the access token
request or can use a HTTP Basic Authentication
header. The authorization server
can also authenticate the client using other mechanisms, such as a
public/private key pair, SSL/TLS client authentication, and the
like.
Depending on the precise use case the Client Credentials flow is used for, a single set of credentials for a client could provide access to a large amount of data. The more data a single set of credentials has access to, the greater the risk if the credentials become compromised. It is extremely critical that the credentials used to authenticate the client be kept highly confidential. Ideally, these credentials would also be regularly rotated.
To demonstrate this flow, we’ll use Facebook’s implementation of App Login with the App Insights service.
The application needs to request an access token from the authorization server, authenticating the request with its client credentials.
You can find the authorization server’s token URL in the API provider’s documentation. For Facebook, the URL is
https://graph.facebook.com/oauth/access_token
Here are the required POST
parameters:
grant_type
Specified as “client_credentials” for this flow.
client_id
The value provided to you when you registered your application.
client_secret
The value provided to you when you registered your application.
Here’s an example request via the curl
command-line HTTP client:
curl -d "grant_type=client_credentials &client_id=2016271111111117128396 &client_secret=904b98aaaaaaac1c92381d2" https://graph.facebook.com/oauth/access_token
If the client credentials are successfully authenticated, an
access token is returned to the client. As Facebook has implemented an
earlier version of the OAuth 2.0 specification as of the time of this
writing, it returns the access_token
in the body of the response using form url-encoding:
access_token=2016271111111117128396|8VG0riNauEzttXkUXBtUbw
The latest draft of the spec (v22) states that the authorization
server should instead return an application/json
response containing the
access_token
:
{ "access_token":"2016271111111117128396|8VG0riNauEzttXkUXBtUbw" }
The access token
is then used
to access the API on behalf of the application itself.
Since the OAuth access token issued by the Client Credentials flow
is a bearer token like the access tokens provided in the other flows, it
can be used similarly. You simply need to provide the access token via a
HTTP Authorization
header or query
parameter value, depending on which the API provider supports.
Here’s an example curl
request,
using a query parameter to pass the access token:
curl "https://graph.facebook.com/202627763128396/insights? access_token=2016271111111117128396|8VG0riNauEzttXkUXBtUbw"
Facebook supports passing the access token as a HTTP Authorization
header as well, but using the
older Authorization: OAuth tokenvalue
instead of Authorization: Bearer
tokenvalue
.
The Client Credentials flow typically provides a long-lived access
token. The authorization server may indicate an expires_in
time; however, the protocol does not
support issuing a refresh token in response to the Client Credentials
flow. Instead, the application simply asks for a new access token if the
current one expires.
3.139.103.204