---
schema_version: "1"
id: eb8eb5ddd3c0992544a55176d61d779077c55ec0ae6fbe68247de734f4ff824d
title: OAuth 2.0 SAML Bearer Assertion Flow for Previously Authorized Apps
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/xcloud/264-0-0/remoteaccess_oauth_SAML_bearer_flow.md
canonical_url: https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_SAML_bearer_flow.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: ee37c3fae79fcae1a3257523692af5bcf3b266027af7e44aa01d52cd4729ac61
description: With the OAuth 2.0 SAML bearer assertion flow, a client—via a connected app—can use previous authorization by supplying a signed SAML 2.0 assertion to request an OAuth access token. The digital signature applied to the SAML assertion authenticates the authorized app. A SAML assertion is an XML security token issued by an identity provider and consumed by a service provider. The service provider relies on its content to identify the assertion’s subject for security-related purposes.
products:
  - Security
  - Cross Cloud
release: "264"
---
# OAuth 2.0 SAML Bearer Assertion Flow for Previously Authorized Apps

With the OAuth 2.0 SAML bearer assertion flow, a client—via a connected app—can use previous authorization by supplying a signed SAML 2.0 assertion to request an OAuth access token. The digital signature applied to the SAML assertion authenticates the authorized app. A SAML assertion is an XML security token issued by an identity provider and consumed by a service provider. The service provider relies on its content to identify the assertion’s subject for security-related purposes.

### Required Editions

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small edition"><colgroup><col></colgroup><tbody><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: both Salesforce Classic and Lightning Experience</td></tr><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: <strong>All</strong> Editions</td></tr></tbody></table>

The OAuth 2.0 SAML bearer assertion flow is similar to a refresh token flow within OAuth. The SAML assertion is posted to the OAuth token endpoint, which in turn processes the assertion and issues an `access_token` based on prior approval of the app. However, the client isn’t required to have or store a `refresh_token`, nor is it required to pass a `client_secret` to the token endpoint.

The OAuth 2.0 SAML bearer assertion flow involves these steps.

1. Create a connected app and register an X509 Certificate. This certificate corresponds to the private key of the app. When the connected app is saved, a consumer key (OAuth `client_id`) is generated and assigned to the app.
2. Write an app that generates a SAML assertion and signs it with the private key.
3. To implement the flow, the connected app posts the SAML bearer assertion to the Salesforce token endpoint.
4. Salesforce validates the signature using the certificate registered for the connected app. In addition, it validates the audience, issuer, subject, and validity of the assertion.
5. Assuming that the assertion is valid and that the user or admin authorized the app previously, Salesforce issues an access token.
    
    ![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_note.png)
    
    Note This flow doesn’t support refresh tokens.

## Create a SAML Bearer Assertion

Create a valid SAML bearer assertion that includes these parameters.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col>
          <col>
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d84404e105">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d84404e108">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e105 ">
              <code>Issuer</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e108 ">The value must be the connected app’s OAuth <code>client_id</code> for which the developer registered their certificate.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e105 ">
              <code>Audience</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e108 ">The value must be <samp class="filepath">https://login.salesforce.com</samp> or
              <samp class="filepath">https://test.salesforce.com</samp>.
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e105 ">
              <code>Recipient</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e108 ">
              <p>The value must be one of these URLs.</p>
              <ul>
                <li><samp class="filepath">https://<var>&lt;My_Domain_Login_URL&gt;</var>/services/oauth2/token</samp></li>
                <li><samp class="filepath">https://login.salesforce.com/services/oauth2/token</samp></li>
                <li><samp class="filepath">https://test.salesforce.com/services/oauth2/token</samp></li>
                <li><samp class="filepath">https://<var>&lt;site_URL&gt;</var>/services/oauth2/token</samp>
                  <p>You
                    can find your My Domain login URL on the My Domain Setup page.</p>
                  <p>If you’re
                    implementing this flow for an Experience Cloud site, enter the site’s URL,
                    such as <samp class="filepath">acme.my.site.com/customers</samp>.</p>
                </li>
              </ul>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e105 ">
              <code>Subject NameID</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e108 ">This value must be the username of the Salesforce user.</td>

          </tr>
        </tbody>
      </table>

The SAML bearer assertion must also conform to these rules.

- The assertion must be signed according to the [XML Signature specification](http://www.w3.org/TR/xmldsig-core/), using RSA and either SHA-1 or SHA-256.
- The SAML assertion must conform with the general format rules specified here: [http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer](http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer).
- When posted to the token endpoint, the assertion must be encoded using base64url encoding as defined here: [http://tools.ietf.org/html/rfc4648#page-7](http://tools.ietf.org/html/rfc4648#page-7)

Here’s a sample assertion.

```
<?xml version="1.0" encoding="UTF-8"?>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_cd3649b3639560458bc9d9b33dfee8d21378409114655" IssueInstant="2013-09-05T19:25:14.654Z" Version="2.0">
  <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">3MVG9PhR6g6B7ps45QoRvhVGGMmR_DT4kxXzVXOo6TTHF3QO1nmqOAstC92 4qSUiUeEDcuGV4tmAxyo_fV8j</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
    <ds:Reference URI="#_cd3649b3639560458bc9d9b33dfee8d21378409114655">
      <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
      <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml"/>
      </ds:Transform>
      </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <ds:DigestValue>N8DxylbIeNg8JDO87WIqXGkoIWA=</ds:DigestValue>
    </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>
XV0lFJrkhJykGYQbIs0JBFEHdt4pe2gBgitcXrscNVX2hKGpwQ+WqjF8EKrqV4Q3/Q4KglrXl/6s
xJr6WOmxWtIQC4oWhSvVyfag34zQoecZeunEdFSMlnvPtqBVzJu9hJjy/QDqDWfMeWvF9S50Azd0
EhJxz/Ly1i28o4aCXQQ=
    </ds:SignatureValue>
    <ds:KeyInfo>
    <ds:X509Data>
    <ds:X509Certificate>
MIICOzCCAaSgAwIBAgIGAR7RRteKMA0GCSqGSIb3DQEBBQUAMGExCzAJBgNVBAYTAlVTMQswCQYD
VQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzENMAsGA1UEChMEUEFDUzENMAsGA1UECxME
U0ZEQzEPMA0GA1UEAxMGU0FNTDIwMB4XDTA5MDExMzE4MzUyN1oXDTE0MDExMTE4MzUyN1owYTEL
MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQK
EwRQQUNTMQ0wCwYDVQQLEwRTRkRDMQ8wDQYDVQQDEwZTQU1MMjAwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAJNGcu8nW6xq2l/dAgbJmSfHLGRn+vCuKWY+LAELw+Kerjaj5Dq3ZGW38HR4BmZk
sG3g4eA1RXn1hiZGI1Q6Ei59QE/OZQx2zVSTb7+oIwRcDHEB1+RraYT3LJuh4JwUDVfEj3WgDnTj
E5vD46l/CR5EXf4VL8uo8T40FkA51AhTAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAehxggY6tBl8x
1SSvCUyUIHvxssAn1AutgZLKWuR1+FXfJzdVdE2F77nrV9YifIERUwhONiS82mBOkKqZZPL1hcKh
KSnFZN2iWmm1sspL73I/eAwVsOUj+bS3v9POo4ceAD/QCCY8gUAInTH0Mq1eOdJMhYKnw/blUyqj
Zn9rajY=
    </ds:X509Certificate>
    </ds:X509Data>
    </ds:KeyInfo>
  </ds:Signature>
<saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">test@example.org</saml:NameID>
  <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:SubjectConfirmationData NotOnOrAfter="2013-09-05T19:30:14.654Z" Recipient="https://login.salesforce.com/services/oauth2/token"/>
  </saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2013-09-05T19:25:14.654Z" NotOnOrAfter="2013-09-05T19:30:14.654Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:AudienceRestriction xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Audience>https://login.salesforce.com/services/oauth2/token</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
  <saml:AuthnStatement AuthnInstant="2013-09-05T19:25:14.655Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml:AuthnContext xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
    </saml:AuthnContext>
  </saml:AuthnStatement>
</saml:Assertion>
```

## Request an Access Token

The connected app posts SAML bearer assertions to the Salesforce token endpoint.

Here’s a sample token request.

```
POST /services/oauth2/token HTTP/1.1
Host: login.salesforce.com
Content-Type: application/x-www-form-urlencoded

grant_type= urn:ietf:params:oauth:grant-type:saml2-bearer&
assertion=PHNhbWxwOl...[omitted for brevity]...ZT
```

When posted, these parameters must be provided.

![Important](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_important.png)

Important When developing OAuth integrations, always pass sensitive information in the body of a POST request or in a request header. Don't use GET parameters in the URL query string to pass sensitive information. Sensitive information includes but isn't limited to usernames, passwords, OAuth tokens, client secrets, and any personally identifiable information. For more information on security best practices, see [Storing Sensitive Data](https://developer.salesforce.com/docs/atlas.en-us.secure_coding_guide.meta/secure_coding_guide/secure_coding_storing_sensitive_data.htm) in the Secure Coding Guide.

 
| Parameter | Description |
| --- | --- |
| `grant_type` | The OAuth 2.0 grant type that the connected app requests. The value must be urn:ietf:params:oauth:grant-type:saml2-bearer |
| `assertion` | The SAML bearer assertion, encoded using base64url as defined here: [http://tools.ietf.org/html/rfc4648#page-7](http://tools.ietf.org/html/rfc4648#page-7). |

You can also include these standard parameters.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col>
          <col>
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d84404e328">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d84404e331">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e328 ">
              <code>format</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e331 ">
              <p>If not included in the request’s header, you can specify the expected return
                format. The <code>format</code> parameter takes precedence
                over the request’s header. These formats are supported.</p>
              <ul>
                <li><code>urlencoded</code></li>
                <li><code>json</code> (default)</li>
                <li><code>xml</code></li>
              </ul>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e328 ">
              <code>scope</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d84404e331 ">You can’t specify scopes in a SAML bearer assertion flow. Instead, the value
              for this parameter is the combination of scopes issued from previous access
              tokens.</td>

          </tr>
        </tbody>
      </table>

## Salesforce Grants an Access Token

After the request is verified, Salesforce sends a response to the client. Token responses for the OAuth 2.0 SAML bearer token flow follow the same format as `authorization_code` flows, although a `refresh_token` is never issued.

![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_note.png)

Note The OAuth 2.0 JWT bearer and SAML assertion bearer flow requests look at all previous approvals for the user that include a refresh token. If Salesforce finds matching approvals, it combines the values of the approved scopes. Salesforce then issues an access token. If Salesforce doesn’t find previous approvals that included a refresh token or any available approved scopes, the request fails as unauthorized.

#### See Also

- [OAuth 2.0 Authorization Errors](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_flow_errors.htm&release=264.0.0&type=5 "Errors can occur during OAuth authorization. For example, a user denies access to the connected app or request parameters are incorrect. When errors occur, the authorizing server sends an error to the callback URL with an error code.")