Last revision 04/10/2014 by Pat patterson(dfc site staging 1330531)

Abstract

OAuth (Open Authorization) is an open protocol to allow secure API authorization in a simple and standardized way from desktop and web applications. The Force.com platform implements the OAuth 2.0 Authorization Framework, so users can authorize applications to access Force.com resources (via the Force.com REST and SOAP Web Service APIs) or Chatter resources (via the Chatter REST API) on their behalf without revealing their passwords or other credentials to those applications. Alternatively, applications can directly authenticate to access the same resources without the presence of an end user.

This article takes an in-depth look at the OAuth 2.0 protocol in the context of Force.com, and is intended for developers and architects with an understanding of security and identity concepts such as authentication and authorization. If you're looking for more of an overview of OAuth 2.0 on Force.com, then Getting Started with the Force.com REST API is a great place to start. If you're interested in learning more about OAuth and Chatter REST API, check out the Chatter REST API Quick Start.

OAuth 2.0 Basics

OAuth is sometimes described as a 'valet key for the web'. In the same way as a valet key gives restricted access to a car, allowing the valet to drive it but not open the trunk or glovebox, OAuth allows a client application restricted access to your data at a resource server via tokens issued by an authorization server in response to your authorization.

OAuthRoles.png

The OAuth 2.0 RFC uses the example of a photo sharing web site (for example, Flickr) as the resource server and a printing service (for example, Snapfish) as the client. You might authorize the printing service (client) for read-only access to some subset of your photos for a limited period of time, after which the authorization becomes invalid. You can even instruct the authorization server to revoke an access token if you decide you no longer wish the client to have access, and don't trust it to discontinue on its own.

Contrast this with giving your credentials (username and password) to a client app so it can access a resource server on your behalf, effectively impersonating you directly. That application now has exactly the same access as you have, to all of your data. Worse, if you decide you no longer trust the client app, your only recourse is to change your password at the resource server and at all the similar client apps you wish to continue using - a major inconvenience! As the previous paragraph shows, OAuth provides a much better solution.

OAuth 2.0 on Force.com

Salesforce.com introduced support for Draft 10 of OAuth 2.0 in the Winter '11 release of Force.com, and has since updated its support to the final OAuth 2.0 RFC. This article uses the terminology from the RFC.

As a Force.com developer, you can use OAuth 2.0 via one of six authentication flows:

(There is also the Refresh Token flow, for renewing tokens issued by the web server or user-agent flows, and the OAuth 1.0a flow, described in Using OAuth to Authorize External Applications).

Note that you should avoid the username and password flow wherever possible, since the other flows free your application from having to manage, store and protect user credentials, but be careful - if you use the web server profile you must store the client secret securely.

You should only use the username and password flow in situations where a user cannot be present at application startup, or with highly privileged applications. In this instance, you should carefully set the API user's permissions to minimize its access as far as possible, and protect the API user's stored credentials from unauthorized access. Such protection is out of the scope of this article, but, for example, you should at least ensure that, if the API user's password is stored in a file on disk, it is not readable by all!

Connected Apps

A connected app (previously known as a 'remote access' app) is an application that integrates with Salesforce using APIs such as the Force.com REST and SOAP APIs. In addition to standard OAuth capabilities, connected apps allow administrators to set various security policies and have explicit control over who may use the applications.

As a developer, you define a connected app by providing OAuth metadata about the application, including:

  • Basic descriptive and contact information for the connected app
  • The OAuth scopes and callback URL for the connected app
  • Optional IP ranges where the connected app might be running
  • Optional information about mobile policies the connected app can enforce

In return, you are provided an OAuth client Id and client secret for the connected app. All of the OAuth 2.0 flows, with the exception of SAML Assertion flow, require that you define a connected app.

Having defined a connected app, you can then package the app and provide it to a Salesforce administrator. There are two deployment modes:

  • The app is created and used in the same organization. This is a typical use case for IT departments, for example.
  • The app is created in one organization and installed on other organizations. This is how an entity with multiple organizations or an ISV would use connected apps.

Tokens, tokens, everywhere!

There are a number of different types of token defined by OAuth 2.0. They each serve a distinct purpose in the protocol, and it's worth taking a few minutes to ensure you understand the differences between them.

Authorization Code

An authorization code is a short-lived token created by the authorization server and passed to the client application via the browser. The client application sends the authorization code to the authorization server to obtain an access token and, optionally, a refresh token.

Access Token

The access token is used by the client to make authenticated requests on behalf of the end user. It has a longer lifetime than the authorization code, typically on the order of minutes or hours. When the access token expires, attempts to use it will fail, and a new access token must be obtained.

In Force.com terms, the access token is effectively a SID or 'session ID', much like a session cookie on other systems, and should be protected against interception, for example by Transport Layer Security (TLS, aka SSL).

Note that if you want to use an OAuth token to access the Force.com Web UI on behalf of the user, either by setting a SID cookie or via the 'front door' URL (e.g. https://na1.salesforce.com/secur/frontdoor.jsp?sid=<sid_value>) you must include web in the list of requested scopes - see the discussion on the scope parameter in the web server flow section below.

Refresh Token

The refresh token may have an indefinite lifetime, persisting for an admin-configured interval or until explicitly revoked by the end-user. The client application can store the refresh token, using it to periodically obtain fresh access tokens, but should be careful to protect it against unauthorized access, since, like a password, it can be repeatedly used to gain access to the resource server.

Since refresh tokens may expire or be revoked by the user outside the control of the client application, the client must handle failure to obtain an access token, typically by replaying the protocol from the start.

ID Token

OpenID Connect defines the ID token, a signed data structure that contains authenticated user attributes including a unique identifier for the end-user, the time at which the token was issued, and an identifier for the client application that requested the token.

The ID token is encoded as a JSON Web Token (JWT).

See Inside OpenID Connect on Force.com for a full discussion of OpenID Connect and ID tokens.

Configuring OAuth 2.0 Access for your Application

Applications using the OAuth 2.0 web server, user-agent, JWT bearer token, SAML bearer assertion and username-password flows must be configured in the Force.com administration console as a connected app (the SAML assertion flow does not require this). For example, if you have a Developer Edition account, log in to Force.com with your developer credentials, navigate to Setup ➤ Create ➤ Apps, and in the Connected Apps section, click New to create a new connected app and click Enable OAuth Settings to open the API section.

NewConnectedApp.png

The 'Callback URL' field, also known as the 'redirect URI', is an endpoint in your application to which Force.com can redirect the user's browser with an authentication code or access token. To protect the token, the only hostname allowed with an 'http' callback URL is 'localhost'. Other hosts must use 'https'. You may alternatively specify a URI with a custom URI scheme - this may be used in the user-agent flow to pass control back to a native application.

If you’re using the JWT Bearer Token or SAML Bearer Assertion flow, select 'Use Digital Signatures' and upload your application's signing certificate.

'Selected OAuth Scopes' control the types of resources that the client application can access in a Salesforce organization. Supported values are:

  • api - Allows access to the current, logged-in user’s account over the APIs, such as the REST API or Bulk API. This value also includes chatter_api, which allows access to Chatter REST API resources.
  • chatter_api - Allows access to only the Chatter REST API resources.
  • full - Allows access to all data accessible by the current, logged-in user. full does not return a refresh token. You must explicitly request the refresh_token scope to get a refresh token.
  • id - Allows access to the Identity Service. You can request profile, email, address, or phone, individually to get the same result as using id; they are all synonymous.
  • openid - Allows access to the current, logged in user’s unique identifier for OpenID Connect apps. The openid scope can be used in the user-agent flow and the web server flow to get back a signed ID token conforming to the OpenID Connect specifications in addition to the access token.
  • refresh_token - Allows a refresh token to be returned if you are eligible to receive one, and is synonymous with requesting offline_access.
  • visualforce - Allows access to Visualforce pages.
  • web - Allows the ability to use the access_token on the Web. This also includes visualforce, allowing access to Visualforce pages.

All scope values automatically include id, so that regardless of which values for scope you pass, you always have access to the Identity Service.

After entering your application's details and clicking Save, you will see your new application’s credentials:

ConnectedAppDetails.png

Click the link to reveal the consumer secret. Note – OAuth 1.0 terminology is currently used in the Connected App screen. Both the OAuth 2.0 specification and this article use the term ‘client’ in place of ‘consumer’.

After you’ve created the connected app, you can specify allowed IP ranges. The IP ranges work with OAuth, not SAML, and specify the addresses that can access the app without requiring the user to use a second factor of authentication, if "bypass with a 2nd factor" is enabled. Once the app is installed, each organization’s administrator can approve or bypass the ranges by setting IP restrictions.

As well as setting allowed IP ranges, you can also specify custom attributes. Use custom attributes to specify SAML metadata or to specify OAuth parameters to be supplied to the app by the Identity Service, for example, user attributes such as 'Title' or 'Department'.

Administering Connected Apps

Administrators can install the connected app into their organization and use profiles, permission sets, and IP range restrictions to control which users can access the application. Management is done from a detail page for the connected app:

ConnectedApp.png

Administrators can also uninstall the connected app and install a newer version. When the app is updated, the developer can notify administrators that there is a new version available for the app.

Administrators can monitor Connected App usage in use in an organization via Setup ➤ Manage Apps ➤ Connected Apps OAuth Usage:

ConnectedAppsOAuthUsage.png

Clicking the user count value drills down into the Connected App User's Usage page, which allows administrators to revoke individual authorizations, or all authorizations for the given app.

ConnectedAppUsersUsage.png

Obtaining an Access Token in a Web Application (Web Server Flow)

Most web applications will use the web server flow (i.e., the authorization code grant type) to obtain an access token on behalf of an end user.

OAuthWebServerFlow.png

The sequence starts (1) with a user requesting some service from the client - in our hypothetical photo-printing example above, the user would be requesting that the photo-printing site print a particular photo.

The client application responds by (2) redirecting the end user's browser to a URL of the following form:

https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>

The following parameters are required (all must be URL encoded):

response_type Must be set to code to request an authorization code.
client_id Your application's client identifier (consumer key in Connected App Detail).
redirect_uri The end user's browser will be redirected to this URI with the authorization code. This must match your application's configured callback URL.

The following optional parameters may also be supplied (again, URL encoded):

display Tailors the login page to the user's device type. Currently the only values supported are:
  • page - Full-page authorization screen (default).
  • popup - Compact dialog optimized for modern web browser popup windows.
  • touch - mobile-optimized dialog designed for modern smartphones, such as Android and iPhone.
  • mobile - mobile optimized dialog designed for less capable smartphones such as BlackBerry OS 5.
immediate Avoid interacting with the user.
  • false - Prompt the user for login and approval (default).
  • true - If the user is currently logged in and has previously approved the client_id, the approval step is skipped, and the browser is immediately redirected to the callback with an authorization code. If the user is not logged in or has not previously approved the client, the flow immediately terminates with the immediate_unsuccessful error code.
login_hint Provide a valid username value with this parameter to pre-populate the login page with the username. For example: login_hint=[email protected]. If a user already has an active session in the browser, then the login_hint parameter does nothing; the active user session continues.
nonce Optional with the openid scope for getting a user ID token. The value is returned in the response and useful for detecting “replay” attacks.
prompt Specifies how the authorization server prompts the user for reauthentication and reapproval. This parameter is optional. The only values Salesforce supports are:
  • login — The authorization server must prompt the user for reauthentication, forcing the user to log in again.
  • consent — The authorization server must prompt the user for reapproval before returning information to the client.

It is valid to pass both values, separated by a space, to require the user to both log in and reauthorize. For example:

  • ?prompt=login%20consent
scope A space separated list of scope values. The scope parameter allows you to fine-tune the permissions associated with the tokens you are requesting, selecting a subset of the values you specified when defining the connected app.
state Any value that you wish to be sent with the callback in step 4.

Assuming immediate is not set, or is set to false, on reaching this login URL, the user will be prompted to authenticate (3) and, if they have not already done so, authorize the client application:

OAuthApproval.png

On successful authorization, the user's browser is redirected back to the redirect URI at the client application (4), with a URL of the form:

https://app.example.com/oauth_callback?code=aWe...c4w%3D%3D&state=<whatever_you_sent_in_step_2>

The client application can now extract the authorization code from its URL parameter and send a direct POST request (5) to the authorization server with URL https://login.salesforce.com/services/oauth2/token and payload of the form

code=aWe...c4w==&grant_type=authorization_code&client_id=<your_client_id>&client_secret=<your_client_secret>&redirect_uri=<your_redirect_uri>

The following parameters are required (again, URL encoded):

code The value returned by the authorization server in the previous step.
grant_type Set this to authorization_code.
client_id Your application's client identifier.
client_secret Your application's client secret (consumer secret in the connected app detail page).
client_assertion Instead of passing in client_secret you can choose to provide a client_assertion and client_assertion_type. If a client_secret parameter is not provided, Salesforce checks for the client_assertion and client_assertion_type automatically.



The value of client_assertion must be a typical JWT bearer token, signed with the private key associated with the OAuth consumer’s uploaded certificate. Only the RS256 algorithm is currently supported. For more information on using client_assertion, see the OpenID Connect specifications for the private_key_jwt client authentication method.

client_assertion_type Provide this value when using the client_assertion parameter.

The value of client_assertion_type must be </code>urn:ietf:params:oauth:client-assertion-type:jwt-bearer</code>.

redirect_uri Again, this must match your application's configuration.

Optionally, you may also provide the following parameter:

format Expected return format. The default is json. Values are:
  • urlencoded
  • json
  • xml

The authorization server should respond with an HTTP status code of 200 and JSON-encoded response payload (reformatted here for readability):

{
	"id":"https://login.salesforce.com/id/00D50000000IZ3ZEAW/00550000001fg5OAAQ",
	"issued_at":"1296458209517",
	"scope": "id full api openid refresh_token chatter_api",
	"instance_url":"https://na1.salesforce.com",
	"token_type": "Bearer",
	"refresh_token":"5Aep862eWO5D.7wJBuW5aaARbbxQ8hssCnY1dw3qi59o1du7ob.lp23ba_3jMRnbFNT5R8X2GUKNA==",
	"id_token": "eyJhb...h97hc",
	"signature":"0/1Ldval/TIPf2tTgTKUAxRy44VwEJ7ffsFLMWFcNoA=",
	"access_token":"00D50000000IZ3Z!AQ0AQDpEDKYsn7ioKug2aSmgCjgrPjG9eRLza8jXWoW7uA90V39rvQaIy1FGxjFHN1ZtusBGljncdEi8eRiuit1QdQ1Z2KSV"
}
id A URL, representing the authenticated user, which can be used to access the Identity Service.
issued_at The time of token issue, represented as the number of seconds since the Unix epoch (00:00:00 UTC on 1 January 1970).
scope A space separated list of scopes that apply to the tokens in the response.
instance_url Identifies the Salesforce instance to which API calls should be sent.
token_type The OAuth 2.0 token type. Currently this is always "Bearer", signifying the bearer token defined in RFC 6750, The OAuth 2.0 Authorization Framework: Bearer Token Usage.
refresh_token A long-lived token that may be used to obtain a fresh access token on expiry of the access token in this response. This value is a secret. You should treat it like the user’s password and use appropriate measures to protect it. See Token Refresh for more details.
id_token A signed JSON Web Token (JWT) that contains authenticated user attributes. This is only returned if the scope parameter includes openid.
signature Base64-encoded HMAC-SHA256 signature signed with the consumer's private key containing the concatenated ID and issued_at. This can be used to verify the identity URL was not modified since it was sent by the server.
access_token The short-lived access token.

At this point, the client application can use the access token to authorize requests against the resource server (the Force.com instance specified by the instance URL) via the REST APIs (6), providing the access token as an HTTP header in each request:

Authorization: Bearer 00D...JeP

(For an explanation of 'Bearer' in this context, see section 1.2 of RFC 6750, The OAuth 2.0 Authorization Framework: Bearer Token Usage.)

The client can continue to send requests to the resource server until the access token expires (8, 9, 10).

The Force.com Identity Service

The 'id' URL that accompanies the access token and instance URL is the gateway to Force.com's Identity Service. You can send a GET request to the id URL, accompanied by an OAuth authorization HTTP header containing the access token, and receive a wealth of information regarding the user and org. (Spaces in the username and email addresses are artifacts of the wiki software - they are not in the data returned by the Identity Service).

{
	"id":"https://login.salesforce.com/id/00D50000000IZ3ZEAW/00550000001fg5OAAQ",
	"asserted_user":true,
	"user_id":"00550000001fg5OAAQ",
	"organization_id":"00D50000000IZ3ZEAW",
	"username":"user@ example. com",
	"nick_name":"user1.2950476911907334E12",
	"display_name":"Sample User",
	"email":"user@ example. com",
	"email_verified": true,
	"first_name": "Sample",
	"last_name": "User",
	"status":{
		"created_date":"2010-11-08T20:55:33.000+0000",
		"body":"Working on OAuth 2.0 article"
	},
	"photos":{
		"picture":"https://c.na1.content.force.com/profilephoto/005/F",
		"thumbnail":"https://c.na1.content.force.com/profilephoto/005/T"
	},
	"addr_street": null,
	"addr_city": null,
	"addr_state": "ca",
	"addr_country": "US",
	"addr_zip": null,
	"mobile_phone": null,
	"mobile_phone_verified": false,
	"urls":{
		"enterprise":"https://na1.salesforce.com/services/Soap/c/{version}/00D50000000IZ3Z",
		"metadata":"https://na1.salesforce.com/services/Soap/m/{version}/00D50000000IZ3Z",
		"partner":"https://na1.salesforce.com/services/Soap/u/{version}/00D50000000IZ3Z",
		"rest":"https://na1.salesforce.com/services/data/v{version}/",
		"sobjects":"https://na1.salesforce.com/services/data/v{version}/sobjects/",
		"search":"https://na1.salesforce.com/services/data/v{version}/search/",
		"query":"https://na1.salesforce.com/services/data/v{version}/query/",
		"recent":"https://na1.salesforce.com/services/data/v{version}/recent/",
		"profile":"https://na1.salesforce.com/00550000001fg5OAAQ"
	},
	"active":true,
	"user_type":"STANDARD",
	"language":"en_US",
	"locale":"en_US",
	"utcOffset":-28800000,
	"last_modified_date":"2011-01-14T23:28:01.000+0000",
	"is_app_installed": true,
	"custom_attributes": {
		"title": "Developer Evangelist"
	}
}

Let's take a closer look at some of the more interesting fields in that response:

asserted_user true if this is the user corresponding to the supplied OAuth token.
user_id The user's Salesforce.com ID.
organization_id The user's org ID.
username The user's login username.
display_name The user's name as displayed in the Salesforce.com user interface.
email The user's email address.
email_verified Indicates whether the organization has email verification enabled (true), or not (false).
status The user's Chatter status.
photos URLs to access the user's picture and thumbnail.
urls URLs for a range of API endpoints.
custom_attributes Any custom attributes you defined as part of the connected app configuration.

Note that the OpenID Connect UserInfo Endpoint provides similar user attributes to the Identity Service. The OpenID Connect UserInfo Endpoint is outside the scope of this document; look for an upcoming article on the topic.

Obtaining an Access Token in a Browser or Native Application (User-Agent Flow)

Client applications, for example, JavaScript running in the browser or native mobile or desktop apps, run on a user's computer or other device. Such apps are able to protect per-user secrets, but, since they are widely distributed, a common client secret would not be secure. The user-agent flow allows these applications to obtain an access token:

OAuthUserAgentFlow.png

In this flow, the client application directs (1) the user to a URL at the authorization server of the form:

https://login.salesforce.com/services/oauth2/authorize?response_type=token&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>&display=touch&state=<some_state>

The following parameters are required (all must be URL encoded):

response_type Value can be token, or token id_token with the scope parameter openid and a nonce parameter,for this flow. If you specify token id_token, Salesforce returns an ID token in the response.
client_id Your application's client identifier (consumer key in Connected App Detail).
redirect_uri The authorization server will respond with a redirect to this URI. This parameter must match your application's configured callback URL.

The following optional parameters may also be supplied (again, URL encoded):

display Tailors the login page to the user's device type. Currently the only values supported are:
  • page - Full-page authorization screen (default).
  • popup - Compact dialog optimized for modern web browser popup windows.
  • touch - mobile-optimized dialog designed for modern smartphones, such as Android and iPhone.
login_hint Provide a valid username value with this parameter to pre-populate the login page with the username. For example: login_hint=[email protected]. If a user already has an active session in the browser, then the login_hint parameter does nothing; the active user session continues.
nonce Optional with the openid scope for getting a user ID token. The value is returned in the response and useful for detecting “replay” attacks.
prompt Specifies how the authorization server prompts the user for reauthentication and reapproval. This parameter is optional. The only values Salesforce supports are:
  • login — The authorization server must prompt the user for reauthentication, forcing the user to log in again.
  • consent — The authorization server must prompt the user for reapproval before returning information to the client.

It is valid to pass both values, separated by a space, to require the user to both log in and reauthorize. For example:

  • ?prompt=login%20consent
scope A space separated list of scope values; see the web server flow for details.
state Any value that you wish to be sent with the callback in step 3.

As in the web server flow, the user is authenticated and prompted to authorize the client application's access to resources (2):

OAuthMobileAuthz.png

Now, rather than sending an authentication code to the client and it retrieving the access token via a POST request, a redirect is returned (3) containing several parameters in a URL fragment (i.e. after the hash '#' sign) - for example:

myapp:oauth#access_token=00D...YjN&refresh_token=5Ae...BiA%3D%3D&instance_url=https%3A%2F%2Fna3.salesforce.com&id=https%3A%2F%2Flogin.salesforce.com%2Fid%2F00D50000000IZ3ZEAW%2F00550000001fg5OAAQ&issued_at=1298926970349&signature=Y5i...D4o%3D&state=mystate

access_token The short-lived access token.
refresh_token A long-lived token that may be used to obtain a fresh access token on expiry of the access token in this response. See Token Refresh for more details. Note that refresh_token is only sent if either of the following is the case:
instance_url Identifies the Salesforce instance to which API calls should be sent.
id A URL, representing the authenticated user, which can be used to access the Identity Service.
id_token A signed JSON Web Token (JWT) that contains authenticated user attributes. This is only returned for a response_type of token id_token, with scope parameter including openid, and a nonce parameter in the request.
issued_at The time of token issue, represented as the number of seconds since the Unix epoch (00:00:00 UTC on 1 January 1970).
signature Base64-encoded HMAC-SHA256 signature signed with the consumer's private key containing the concatenated ID and issued_at. This can be used to verify the identity URL was not modified since it was sent by the server.
state If a value was provided for the state parameter in the request, then that same value will be returned here.
token_type The OAuth 2.0 token type; currently this is always "Bearer".

Since these parameters are passed in a fragment, they will remain on the client device, and will not be passed in an HTTP GET to the redirect URI. Note that the redirect URI may have a custom scheme, configured in the desktop/device OS to invoke a callback in the native app, for example, myapp:oauth, it may have the https scheme, or it may have the http scheme, for localhost only.

A native application can directly parse the incoming parameters from the fragment; in contrast a browser-based application would rely on JavaScript, served from the https redirect URI, which would have access to the fragment and its parameters.

Either way, on receipt of the access token, the client application is able to send requests to the resource server (the Force.com instance specified by the instance URL) via the REST APIs (6), providing the access token as an HTTP header in each request:

Authorization: Bearer 00D50000000IZ3Z!AQ0AQDpEDKYsn7ioKug2aSmgCjgrPjG...

Obtaining an Access Token using a JWT Bearer Token

OAuthJWTBearerTokenFlow.png

JSON Web Token (JWT, pronounced as the English word 'jot') is a JSON-based security token encoding that enables identity and security information to be shared across security domains.

The OAuth 2.0 JWT Bearer Token Flow defines how a JWT can be used to request an OAuth access token from Salesforce when a client wishes to utilize a previous authorization. Among other data, the JWT contains the username for which an access token is required, and the client_id of the requesting app. Authentication of the requesting app is provided by a digital signature applied to the JWT.

JWT Bearer Token Flow supports the RSA/SHA256 algorithm; you must upload your app's signing certificate to its connected app configuration so that Salesforce can verify its JWT tokens.

In the JWT Bearer Token Flow, the JWT is POSTed (1) to the OAuth token endpoint, https://login.salesforce.com/services/oauth2/token, with payload of the form:

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=PHN...QZT

grant_type Set this to urn:ietf:params:oauth:grant-type:jwt-bearer
assertion The JWT bearer token.

The authorization server validates the JWT and issues an access_token (2) based upon prior approval of the application. However, the client doesn’t need to have or store a refresh_token; the client creates a new JWT when it needs another access_token. Note also that a client_secret is not required to be passed to the token endpoint - the JWT authenticates the app.

The OAuth 2.0 JWT Bearer Token Flow documentation describes the JWT format and contains detailed steps and sample Java code for creating JWTs.

Obtaining an Access Token using a SAML Bearer Assertion

OAuthSAMLBearerAssertionFlow.png

A SAML 2.0 Assertion is an XML security token, generally issued by an identity provider and consumed by a service provider who relies on its content to identify the Assertion’s subject for security-related purposes.

The OAuth 2.0 SAML Bearer Assertion Flow defines how a SAML Assertion can be used to request an OAuth access token when a client wishes to utilize a previous authorization. As in the JWT Bearer Token Flow, the user must have previously authorized the application. The app creates a SAML Assertion containing, amongst other data, the username for which an access token is required, and the client_id of the app. Authentication of the authorized application is provided by the digital signature applied to the SAML Assertion.

In the SAML Bearer Assertion Flow, the Assertion is POSTed (1) to the OAuth token endpoint, https://login.salesforce.com/services/oauth2/token, with payload of the form:

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2-bearer&assertion=PHN...QZT

grant_type Set this to urn:ietf:params:oauth:grant-type:saml2-bearer
assertion The SAML Bearer Assertion, encoded using base64url.

The authorization server validates the Assertion and issues an access_token (2) based upon prior approval of the application. As in the JWT Bearer Token Flow, the client doesn’t need to have or store a refresh_token; the client creates a new SAML Assertion when it needs another access_token. Again, a client_secret is not required to be passed to the token endpoint - the Assertion authenticates the app.

The OAuth 2.0 SAML Bearer Assertion Flow documentation contains an example SAML Assertion.

Obtaining an Access Token using a Web SSO SAML Assertion

OAuthSAMLBearerAssertionFlow.png

The SAML Assertion flow is an alternative for organizations that are currently using SAML to access Salesforce, and want to access APIs the same way. The SAML Assertion flow can only be used inside a single organization. Clients can use this to access the API using a SAML Assertion in much the same way as they would federate with Salesforce for Web single sign-on.

In contrast with the SAML Bearer Assertion Flow, you do not have to create a connected app to use this assertion flow. The SAML Assertion Flow uses the SAML settings configured in your org for single sign-on. Your application must obtain or generate a valid SAML response and POST this (1) to the token endpoint, https://login.salesforce.com/services/oauth2/token, with payload of the form:

grant_type=assertion&assertion_type= urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aprofiles%3ASSO%3Abrowser&assertion=PHN...QZT

grant_type Set this to assertion
assertion The SAML Assertion, encoded using base64 (not base64url).
assertion_type Set this to urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser

Optionally, you can include the following:

format Expected return format. The default is json. Values are:
  • urlencoded
  • json
  • xml

The SAML Assertion Flow documentation contains more detail on configuring SAML for OAuth.

Token Refresh

OAuthRefreshFlow.png

The lifetime of an access token obtained by the above mechanisms is limited to the session timeout configured in Setup ➤ Security Controls ➤ Session Settings. When an access token expires, attempts to use it (2) will result in an error response (3). The details of the response vary with the protocol in use; the SOAP API will return a SOAP fault with a faultcode of sf:INVALID_SESSION_ID, while the REST API will return a 401 HTTP status code and a JSON-encoded body of

[
    {
        "errorCode": "INVALID_SESSION_ID", 
        "message": "Session expired or invalid"
    }
]

In this situation, the client application can use the refresh token to obtain a new access token. The refresh token represents the user's authorization to the application, and is valid until explicitly revoked by the user, via My Settings ➤ Personal ➤ Advanced User Details ➤ OAuth Connected Apps.

The client application obtains a new access token by POSTing another request (4) to https://login.salesforce.com/services/oauth2/token, this time with payload of the form:

grant_type=refresh_token&client_id=3MVG9lKcPoNINVBJGKrUKSXjJRTgKoeZx6OvJLXwLO8n80_OY.ydx0cQ24zGwBhRfa4YEWrFaNVVdI142EivZ&client_secret=7868057769520845245&refresh_token=5Aep861eWO5D.7wJBuW5aaARbbxQ8hssCnY1dw3qi59o1du7ob.lp23ba_3jMRnbFNT5R8X2GUKNA==

grant_type Set this to refresh_token.
client_id Your application's client identifier.
client_secret Your application's client secret (optional).
refresh_token The refresh token provided in the previous authorization.

On receipt of the access token, the client can repeat its request (5), send a response to the user (6), and carry on servicing requests (7, 8, 9) until the new access token expires.

Obtaining a Token in an Autonomous Client (Username and Password Flow)

OAuthAutonomousClientFlow.png

An autonomous client can obtain an access token by simply providing username, password and (depending on configuration) security token in an access token request. Again the request is POSTed (1) to https://login.salesforce.com/services/oauth2/token, but the payload now has the form

grant_type=password&client_id=<your_client_id>&client_secret=<your_client_secret>&username=<your_username>&password=<your_password>

The following parameters are required:

grant_type Set this to password.
client_id Your application's client identifier.
client_secret Your application's client secret.
username The API user's Salesforce.com username, of the form [email protected]
password The API user's Salesforce.com password. If the client's IP address has not been whitelisted in your org, you must concatenate the security token with the password.

You will receive a similar response to the authorization code case:

{
	"id":"https://login.salesforce.com/id/00D50000000IZ3ZEAW/00550000001fg5OAAQ",
	"issued_at":"1296509381665",
	"instance_url":"https://na1.salesforce.com",
	"signature":"+Nbl5EOl/DlsvUZ4NbGDno6vn935XsWGVbwoKyXHayo=",
	"access_token":"00D50000000IZ3Z!AQgAQH0Yd9M51BU_rayzAdmZ6NmT3pXZBgzkc3JTwDOGBl8BP2AREOiZzL_A2zg7etH81kTuuQPljJVsX4CPt3naL7qustlb"
}

You will notice that there is no refresh token in the response. Since the user is not redirected to login at Salesforce, there is no opportunity for the user to authorize the application. Such an authorization is required for a refresh token to be issued. If your application requires a refresh token, you should carefully consider moving to a different flow if at all possible.

Summary

Force.com's implementation of OAuth 2.0 allows client applications to access resources on behalf of end users without sharing credentials such as passwords with those client applications, enhancing both privacy and security. This article provides a description of OAuth as well as the various authentication flows supported by OAuth.

References

About the Author

Pat Patterson is a Developer Evangelist Architect at salesforce.com. Describing himself as an 'articulate techie', Pat hacks all manner of code from Node.js web apps down to Linux kernel drivers, writing it all up on the Force.com blog, his own blog Superpatterns, tweeting along the way.