Loading
Identification de vos utilisateurs et gestion de l’accès
Flux de porteur JWT OAuth 2.0 pour l'intégration serveur à serveur

Flux de porteur JWT OAuth 2.0 pour l'intégration serveur à serveur

Vous souhaitez parfois authentifier des serveurs pour accéder aux données sans consigner chaque fois interactivement les informations d'échange des serveurs. Dans ce cas, vous utilisez le flux de porteur du jeton Web JSON (JWT) OAuth 2.0. Ce flux utilise un certificat pour signer la requête JWT et ne nécessite pas l'interaction explicite de l'utilisateur. Ce flux nécessite toutefois l'approbation préalable de l'application cliente.

Éditions requises

Disponible avec : Salesforce Classic et Lightning Experience
Disponible avec : Toutes les éditions
Remarque
Remarque La création d'applications connectées est limitée à compter de la version Spring ‘26. Vous pouvez continuer à utiliser des applications connectées existantes pendant et après la version Spring ‘26. Nous recommandons toutefois d'utiliser à la place des applications clientes externes. Si vous devez continuer à créer des applications connectées, contactez le Support Salesforce.

Pour plus d'informations, consultez Nouvelles applications connectées ne peuvent plus être créées dans Spring ‘26.

Avec le flux de jeton du porteur JWT OAuth 2.0, le client publie un JWT au point de terminaison de jeton OAuth Salesforce. Salesforce traite le JWT, qui inclut une signature numérique, puis émet un jeton d'accès basé sur l'approbation préalable de l'application.

Cet exemple montre les étapes suivies par le flux.

  1. Un service de rapport commence par un rapport par lot généré de nuit.
  2. L'application connectée envoi le JWT au point de terminaison de jeton Salesforce. Le JWT permet de partager des informations d'identité et de sécurité entre des domaines de sécurité.
  3. Salesforce valide le JWT basé sur une signature en utilisant le certificat précédemment configuré et des paramètres supplémentaires.
  4. Considérant que le JWT est valide et que l'application connectée a déjà autorisée, Salesforce émet un jeton d'accès. L'approbation précédente est effectuée avec l'une des méthodes ci-dessous.
    • Si votre stratégie d'application connectée est définie sur Les utilisateurs approuvés par l'administrateur sont pré-autorisés, vous pouvez utiliser des profils et des ensembles d'autorisations.
    • Si votre stratégie d'application connectée est définie sur Tous les utilisateurs peuvent s'autoriser eux-mêmes, vous pouvez utiliser l'approbation de l'utilisateur et émettre un jeton d'actualisation. Cependant, il n'est pas nécessaire que le client dispose d'un jeton d'actualisation actuel ou stocké. Le client ne doit pas non plus transmettre de secret client au point de terminaison de jeton.
    Remarque
    Remarque Pour les deux options, Salesforce émet un nouveau jeton d'accès uniquement lorsque le jeton d'accès d'origine inclut au moins une étendue standard différente de l'étendue refresh_token.
  5. L'application connectée utilise le jeton accès pour accéder aux données protégées dans le serveur Salesforce.
  6. Le service de rapport extrait les données autorisées dans son rapport généré de nuit.
Remarque
Remarque Ce flux n'émet jamais de jeton d'actualisation.

Examinons chaque étape de ce flux d'autorisation.

Créer un JWT

Salesforce nécessite un JWT signé en utilisant le protocole RSA SHA256, qui utilise un certificat chargé en tant que secret de signature. Avant d'utiliser ce flux d'autorisation, assurez-vous de suivre les étapes ci-dessous.

  • Chargez un certificat X509 dans un magasin de clés Java (JKS). La taille du certificat ne peut pas dépasser 4 Ko. En cas de dépassement, essayez d'utiliser un fichier codé en DER pour réduire la taille.
  • Enregistrez le certificat X509 pour l'application connectée. Le certificat correspond à la clé privée de son application. Lorsque l'application connectée est enregistrée, le client_id et le client_secret sont générés et attribués à l'application.
  • Élaborez une application qui génère un JWT, signé avec la clé privée du certificat X509. L'application connectée associée utilise le certificat pour vérifier la signature. Le JWT doit respecter les règles de format générales spécifiées à l'adresse https://tools.ietf.org/html/rfc7519.
    Remarque
    Remarque Salesforce ne nécessite pas de réclamations JWT ID (JTI) dans vos jetons de porteur JWT. Cependant, si vous transmettez une réclamation JTI à votre jeton de porteur JWT, Salesforce vérifie que la réclamation JTI n'a pas été envoyée avant. La validation empêche les attaques en relecture JWT.

Pour créer un JWT valide, procédez comme suit.

  1. Construisez un en-tête JWT sous le format suivant : {"alg":"RS256"}.
  2. Base64url encode l'en-tête JWT selon la définition spécifiée à l'adresse http://tools.ietf.org/html/rfc4648#page-7. Le résultat est similaire à eyJhbGciOiJSUzI1NiJ9.
  3. Construisez un ensemble de réclamations JSON pour le JWT avec les paramètres ci-dessous.
    Paramètre Description
    iss L'émetteur doit contenir le client_id OAuth ou l'application connectée pour laquelle le développeur a enregistré le certificat.
    aud

    L'audience identifie le serveur d'autorisation en tant qu'audience ciblée. Le serveur d'autorisation doit vérifier qu'elle est une audience ciblée pour le jeton.

    Utilisez l'URL du serveur d'autorisation pour la valeur d'audience : https://login.salesforce.com, https://test.salesforce.com, ou https://site.force.com/customers s'il est implémenté pour un site Experience Cloud.

    sub

    Si vous implémentez ce flux pour un site Experience Cloud, l'objet doit contenir le nom d'utilisateur.

    Pour la rétro-compatibilité, vous pouvez utiliser le principal (prn) au lieu de l'objet (sub). Si les deux sont spécifiés, prn est utilisé.

    exp La date et l'heure d'expiration du jeton, exprimées en nombre de secondes depuis 1970-01-01T0:0:0Z mesurée en heure UTC. Salesforce autorise un écart d'horloge de trois minutes. Par exemple, si l'heure d'expiration est définie sur 1,735,743,600 secondes ou le 1er janvier 2025 à 15:00:00 UTC, le jeton est toujours valide jusqu'à 15:03:00 UTC à cette date.
    Voici un exemple d'ensemble de réclamations JSON pour le JWT.
    {"iss": "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQ
    ukXnVjzRgSuQqGn75NL7yfkQcyy7", 
    "sub": "my@email.com", 
    "aud": "https://login.salesforce.com", 
    "exp": "1333685628"}
  4. Codez le JWT Claims Set en Base64url sans aucun saut de ligne. Par exemple :
    eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
    Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu
    Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz
    Njg1NjI4In0=
  5. Créez une chaîne avec l'en-tête JWT Header codé et le JWT Claims Set codé, sous le format suivant :
    encoded_JWT_Header + "." + encoded_JWT_Claims_Set
    Dans cet exemple, l'en-tête JWT codé est mis en évidence :
    eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
    Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu
    Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz
    Njg1NjI4In0=
  6. Téléchargez le certificat X509 depuis le JKS.
  7. Signez la chaîne générée en utilisant RSA SHA256.
  8. Créez une chaîne à partir de la chaîne à cette étape, sous ce format.
    existing_string + "." + base64_encoded_signature
    Dans cet exemple, la signature codée en base64 est mise en évidence.
    eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
    Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu
    Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz
    Njg1NjI4In0=.iYCthqWCQucwi35yFs-nWNgpF5NA_a46fXDTNIY8ACko6BaEtQ9E6h4Hn1l_pcwcK​
    I_GlmfUO2dJDg1A610t09TeoPagJsZDm_H83bsoZUoI8LpAA1s-2aj_Wbysqb1j4uDToz​
    480WtEbkwIv09sIeS_-QuWak2RXOl1Krnf72mpVGS4WWSULodgNzlKHHyjAMAHiBHIDNt​
    36y2L2Bh7M8TNWiKa_BNM6s1FNKDAwHEWQrNtAeReXgRy0MZgQY2rZtqT2FcDyjY3JVQb​
    En_CSjH2WV7ZlUwsKHqGfI7hzeEvVdfOjH9NuaJozxvhPF489IgW6cntPuT2V647JWi7ng

Ce code Java est un simple exemple de création d'un jeton du porteur JWT.

import org.apache.commons.codec.binary.Base64;
import java.io.*; 
import java.security.*; 
import java.text.MessageFormat;  

public class JWTExample {

  public static void main(String[] args) {

    String header = "{\"alg\":\"RS256\"}";
    String claimTemplate = "'{'\"iss\": \"{0}\", \"sub\": \"{1}\", \"aud\": \"{2}\", \"exp\": \"{3}\", \"jti\": \"{4}\"'}'";

    try {
      StringBuffer token = new StringBuffer();

      //Encode the JWT Header and add it to our string to sign
      token.append(Base64.encodeBase64URLSafeString(header.getBytes("UTF-8")));

      //Separate with a period
      token.append(".");

      //Create the JWT Claims Object
      String[] claimArray = new String[5];
      claimArray[0] = "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQukXnVjzRgSuQqGn75NL7yfkQcyy7";
      claimArray[1] = "my@email.com";
      claimArray[2] = "https://login.salesforce.com";
      claimArray[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
      claimArray[4]=<JTI>
      MessageFormat claims;
      claims = new MessageFormat(claimTemplate);
      String payload = claims.format(claimArray);

      //Add the encoded claims object
      token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8")));

      //Load the private key from a keystore
      KeyStore keystore = KeyStore.getInstance("JKS");
      keystore.load(new FileInputStream("./path/to/keystore.jks"), "keystorepassword".toCharArray());
      PrivateKey privateKey = (PrivateKey) keystore.getKey("certalias", "privatekeypassword".toCharArray());

      //Sign the JWT Header + "." + JWT Claims Object
      Signature signature = Signature.getInstance("SHA256withRSA");
      signature.initSign(privateKey);
      signature.update(token.toString().getBytes("UTF-8"));
      String signedPayload = Base64.encodeBase64URLSafeString(signature.sign());

      //Separate with a period
      token.append(".");

      //Add the encoded signature
      token.append(signedPayload);

      System.out.println(token.toString());

    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}

Demander un jeton d'accès

Pour demander un jeton d'accès, l'application connectée publie une demande de jeton au point de terminaison de jeton de l'instance Salesforce. Elle inclut le JWT dans la publication.

Cet exemple présente un exemple de demande de jeton.

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

grant_type= urn:ietf:params:oauth:grant-type:jwt-bearer&
assertion=eyJpc3MiOiAiM01WRz...[omitted for brevity]...ZT
Important
Important Lors du développement d'intégrations OAuth, transmettez toujours des informations confidentielles dans le corps d'une requête POST ou dans un en-tête de requête. N'utilisez pas les paramètres GET dans la chaîne de requête URL pour transmettre des informations confidentielles. Les informations confidentielles comprennent, sans s'y limiter, les noms d'utilisateur, les mots de passe, les jetons OAuth, les secrets clients et toute information d'identification personnelle. Pour plus d'informations sur les meilleures pratiques de sécurité, consultez Stockage des données confidentielles dans le Secure Coding Guide.

Insérez les paramètres ci-dessous dans la publication.

Paramètre Description
grant_type Utilisez les valeurs suivantes pour le type d'autorisation d'accès : urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion L'assertion est la valeur JWT complète.
format

(Facultatif) Utilisez-le pour spécifier le format de retour attendu. Ce paramètre remplace l'en-tête de la requête. Les formats suivants sont pris en charge :

  • urlencoded
  • json (par défaut)
  • xml

Paramètre d'étendue

Vous ne pouvez pas spécifier d'étendue dans un flux de jeton du porteur JWT. Les étendues sont émises en fonction de la stratégie Utilisateurs autorisés de l'application connectée, ou des paramètres de Contrôle d'accès API de votre organisation, comme indiqué dans le tableau ci-dessous.

Paramètre Résultat
Stratégie Utilisateurs autorisés : Tous les utilisateurs peuvent s’autoriser eux-mêmes Lorsqu'une autorisation réussit, les étendues renvoyées avec le jeton d'accès sont dérivées à partir des étendues des approbations précédentes.
Stratégie Utilisateurs autorisés : Les utilisateurs approuvés par l'administrateur sont pré-autorisés Les étendues standard et personnalisées attribuées à l'application connectée sont renvoyées avec le jeton d'accès.
Contrôle d'accès API : Les applications connectées de la liste d'autorisations de votre organisation

Les étendues standard et personnalisées attribuées à l'application connectée sont renvoyées avec le jeton d'accès. Si vous ajoutez des applications connectées à la liste d'autorisations de votre organisation et ne recevez pas les étendues attendues, procédez comme suit.

  • Dans Configuration, saisissez OAuth dans la case Recherche rapide, puis sélectionnez Utilisation d'applications connectées OAuth.
  • Pour l'application connectée de la liste d'autorisations, cliquez sur Bloquer.
  • Pour l'application connectée de la liste d'autorisations, cliquez sur Débloquer.

Salesforce accorde un jeton d'accès

Les requêtes de flux de porteur JWT et de porteur d'assertion SAML OAuth 2.0 examinent toutes les approbations précédentes de l'utilisateur qui contiennent un jeton d'actualisation. Si Salesforce renvoie des approbations correspondantes, les valeurs des étendues approuvées son combinées. Salesforce émet ensuite un jeton d'accès. Si Salesforce ne trouve aucune approbation précédente contenant un jeton d'actualisation ni d'étendues approuvées disponibles, la demande échoue et n'est pas autorisée.

Une fois la vérification effectuée, l'instance Salesforce envoie une réponse à l'application connectée. Une réponse de jeton pour le flux de jeton du porteur OAuth 2.0 JWT respecte le même format qu'un flux code d'autorisation, bien qu’aucun jeton d'actualisation ne soit émis.

Cet exemple présente une réponse de Salesforce.

{"access_token":"00Dxx0000001gPL!AR8AQJXg5oj8jXSgxJfA0lBog.
39AsX.LVpxezPwuX5VAIrrbbHMuol7GQxnMeYMN7cj8EoWr78nt1u44zU31
IbYNNJguseu",
"scope":"web openid api id","instance_url":"
https://yourInstance.salesforce.com","id":"
https://yourInstance.salesforce.com
/id/00Dxx0000001gPLEAY/005xx000001SwiUAAS","token_type":"Bearer"}

Les paramètres suivants sont inclus dans le corps de la réponse.

Paramètre Description
access_token Le jeton OAuth utilisé par une application connectée pour demander l'accès à une ressource protégée au nom de l'application cliente. Des autorisations supplémentaires sous forme d'étendues peuvent accompagner le jeton d'accès.
token_type Un type de jeton Bearer, utilisé pour toutes les réponses qui incluent un jeton d'accès.
scope Les étendues sont émises en fonction de la stratégie Utilisateurs autorisés de l'application connectée, ou des paramètres de Contrôle d'accès API de votre organisation. Consultez Paramètre d'étendue.
instance_url Une URL indiquant l'instance de l'organisation de l'utilisateur. Par exemple : https://yourInstance.salesforce.com/.
id Une URL d'identité qui peut être utilisée pour identifier l'utilisateur et pour demander plus d'informations sur l'utilisateur. Consultez URL d'identité.
sfdc_site_url Si l'utilisateur est membre d'un site Experience Cloud, l'URL du site est fournie.
sfdc_site_id Si l'utilisateur est membre d'un site Experience Cloud, l'ID du site de l'utilisateur est fourni. Pour des sites Experience Cloud, ce flux inclut la valeur "sfdc_site_id" dans le point de terminaison de jeton. Cet ID de site est toujours requis dans les requêtes de l'API REST Connect.

Accéder aux données protégées

Lorsque l'application connectée reçoit le access_token, elle peut le transmettre en tant que jeton de porteur dans l'en-tête de la requête d'autorisation. Cet exemple présente un appel d'API REST à des sites Experience Cloud :


          https://site.force.com/customers/services/data/v32.0/ -H 
"Authorization: Bearer 00D50000000IehZ\!AQcAQH0dMHZfz972Szmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1E6 LYUfiDUkWe6H34r1AAwOR8B8fLEz6n04NPGRrq0FM"
        
 
Chargement
Salesforce Help | Article