Loading
Salesforce now sends email only from verified domains. Read More
Identify Your Users and Manage Access
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          OAuth 2.0 SAML Bearer Assertion Flow for Previously Authorized Apps

          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

          Available in: both Salesforce Classic and Lightning Experience
          Available in: All Editions

          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
            Note This flow doesn’t support refresh tokens.

          Create a SAML Bearer Assertion

          Create a valid SAML bearer assertion that includes these parameters.

          Parameter Description
          Issuer The value must be the connected app’s OAuth client_id for which the developer registered their certificate.
          Audience The value must be https://login.salesforce.com or https://test.salesforce.com.
          Recipient

          The value must be one of these URLs.

          • https://<My_Domain_Login_URL>/services/oauth2/token
          • https://login.salesforce.com/services/oauth2/token
          • https://test.salesforce.com/services/oauth2/token
          • https://<site_URL>/services/oauth2/token

            You can find your My Domain login URL on the My Domain Setup page.

            If you’re implementing this flow for an Experience Cloud site, enter the site’s URL, such as acme.my.site.com/customers.

          Subject NameID This value must be the username of the Salesforce user.

          The SAML bearer assertion must also conform to these rules.

          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
          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 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.

          You can also include these standard parameters.

          Parameter Description
          format

          If not included in the request’s header, you can specify the expected return format. The format parameter takes precedence over the request’s header. These formats are supported.

          • urlencoded
          • json (default)
          • xml
          scope 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.

          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
          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.
           
          Loading
          Salesforce Help | Article