Chapter 4. Resource Owner Password Flow

The Resource Owner Password Credentials flow allows exchanging the username and password of a user for an access token and, optionally, a refresh token. This flow has significantly different security properties than the other OAuth flows. The primary difference is that the user’s password is accessible to the application. This requires strong trust of the application by the user.

Figure 4-1 shows a step-by-step flow diagram, based on a diagram from the specification.

Resource Owner Password flow: Step-by-step
Figure 4-1. Resource Owner Password flow: Step-by-step

When Should the Resource Owner Password Flow Be Used?

Because the resource owner’s password is exposed to the application, this flow should be used sparingly. It is recommended only for first-party “official” applications released by the API provider, and not opened up to wider third-party developer communities.

If a user is asked to type their password into “official” applications, they may become accustomed to doing so and become vulnerable to phishing attempts by other apps. In order to mitigate this concern, developers and IT administrators should clearly educate their users how they should determine which apps are “official” and which are not.

Security Properties

Although the application has access to the resource owner’s password, there are still some security benefits to using this flow versus authenticating API calls with a username and password (via HTTP Basic access authentication or similar). With Basic authentication, an application needs to have continuous access to the user’s password in order to make API calls. It also requires the user change their password and reenter the new password in all applications which require it, should the user no longer want an application to have access to their data.

However, if the OAuth Resource Owner Password flow is used, the application only needs access to the user’s credentials once: on first use when the credentials are exchanged for an access token. This means there’s no requirement for the app to store these credentials within the application or on the device, and revoking access is easy as well.

User Experience

The user experience for this flow is identical to typical password-based access requests. The application asks the user for their username and password and the user provides the information. The application then makes either a server-side or client-side request to the API provider’s authorization server, without any user-facing interface changes.

If the API provider does not issue a refresh_token and the issued access_token is short-lived, the application will likely store the username and password for future authentication attempts. Unfortunately, this defeats some of the benefit of this flow.

Step-by-Step

To demonstrate this flow, we’ll use an example built on top of Salesforce’s REST-based APIs. Our example will retrieve and output all contacts accessible to the resource owner in the Salesforce CRM system.

We’ll assume the example application is a native mobile application written by Acme Corporation and distributed to its employees through a corporate application directory. This method of distribution indicates to the employees that it is a “trusted” application and it’s OK to enter their credentials in the app.

Step 1: Ask the user for their credentials

The first step is asking the user to provide their credentials to the application. In addition to a username and password, Salesforce requires that a user enter their security token when logging into an app from an untrusted network, such as the networks used by popular mobile phone service providers. An application would typically display this as a third field for user input, in addition to the username and password.

Step 2: Exchange the credentials for an access token

The process of exchanging credentials for an access token is very similar to exchanging an authorization code for an access token in the Authorization Code flow. We simply need to make a HTTP POST to the authorization server, providing the credentials and client information.

You can find the authorization server URL in the API provider’s documentation. For Salesforce, the URL is

https://login.salesforce.com/services/oauth2/token

Here are the required POST parameters:

grant_type

Specified as “password” for this flow.

scope

The data your application is requesting access to. It is not required for Salesforce and is optional for other APIs. The Winter ’12 version of Salesforce introduces optional values for this parameter.

client_id

The value provided to you when you registered your application. Although optional in the spec, this value is required by Salesforce. Registration of the app is achieved using the App SetupDevelopRemote Access menu.

client_secret

The value provided to you when you registered your application. While the name of this parameter implies that the value is secret, it is sometimes required by API providers for nonconfidential clients such as native mobile applications. In these cases, the value is not actually a secret, as it could be discovered by users of the application.

username

The username provided by the resource owner, encoded as UTF-8.

password

The password provided by the resource owner, encoded as UTF-8. For Salesforce, you need to concatenate the security token entered by the user at the end of the entered password and pass the combined value as the value of this parameter.

Here’s an example request via the curl command-line HTTP client:

curl -d "grant_type=password" \
-d "client_id=3MVG9QDx8IKCsXTFM0o9aE3KfEwsZLvRt" \
-d "client_secret=4826278391389087694" \
-d "username=ryan%40ryguy.com" \
-d "password=_userspassword__userssecuritytoken_" \
https://login.salesforce.com/services/oauth2/token

If the user-provided credentials are successfully authenticated, the Salesforce OAuth authorization server will return an application/json response containing an access_token:

{
  "id":"https://login.salesforce.com/id/00DU0000000Io8rMAC/005U0000000hMDCIA2",
  "issued_at":"1316990706988",
  "instance_url":"https://na12.salesforce.com",
  "signature":"Q2KTt8Ez5dwJ4Adu6QttAhCxbEP3HyfaTUXoNI=",
  "access_token":"00DU0000000Io8r!AQcKbNiJPt0OCSAvxU2SBjVGP6hW0mfmKH07QiPEGIX"
}

What do each of these response parameters mean?

access_token

The access token used to access the API on behalf of the user who provided their credentials. This is the only required item in the response.

id (Salesforce-specific value)

The unique identity of the user. This URL can also be accessed as any other OAuth-protected resource to obtain more information about the user. The user metadata is returned as JSON or XML, depending on the value of the HTTP Accept header sent in the request.

instance_url

The URL prefix the client application should use to access the API. This response parameter is specific to Salesforce’s implementation.

signature

A signature used to validate that the identity URL hasn’t been modified since being sent from the server. Although Salesforce issues signatures that can be verified, it isn’t strictly necessary; instead, the application can use the built-in protections of HTTPS to ensure communication with Salesforce’s servers. This response parameter is specific to Salesforce’s implementation.

issued_at (Salesforce-specific value)

The time the signature was generated, used for validating it.

Step 3: Call the API

Since the OAuth access token issued by the authorization flow is a simple bearer token like the access tokens provided in the other flows (as described in Step 3: Call the API), 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:

curl -d "q=SELECT+name+FROM+Account"\
-H 'Authorization: Bearer 00DU0000000Io8r!AQcAQKJ.Cg1dCBCVHmx2.Iu3lroPQBV2P65_jXk'
"https://na12.salesforce.com/services/data/v20query"

Step 4: Refresh the access token

Although Salesforce does not support refreshing the access token when using this flow, the spec does accommodate it using the method described in Step 4a: Refresh the access token.

It is important that clients have a way of refreshing the access token if it is issued with only a short-term lifespan. This prevents developers from needing to store the provided user credentials within their applications—one of the major benefits of this flow versus traditional HTTP Basic access authentication mechanisms.

Get Getting Started with OAuth 2.0 now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.