Migrate to Access Tokens for Account Linking (Migrer vers des jetons d’accès pour associer les comptes)

Auparavant, il était possible d’utiliser des jetons d’ID pour associer et désassocier des comptes d’utilisateurs dans certains cas d’utilisation. Auth0 supprime cette fonctionnalité. Vous devrez désormais utiliser des jetons d’accès dans tous les cas.

Fonctionnalités affectées

Les modifications dans l’association des comptes sont :

  • Vous ne pouvez plus utiliser de jeton d’ID dans l’en-tête Authorization, un jeton d’accès doit être utilisé à la place.

  • Si vous utilisez un jeton d’accès dans l’en-tête Authorization, avec update:users comme permission accordée, vous pouvez envoyer comme le corps de la requête soit le user_id, soit le jeton d’ID du compte secondaire.

  • Si vous utilisez un jeton d’accès dans l’en-tête Authorization, avec update:current_user_metadata comme permission accordée, vous ne pouvez envoyer que le jeton d’ID du compte secondaire dans le corps de la requête.

  • Si vous envoyez le jeton d’ID du compte secondaire dans le corps de la requête (cas d’utilisation décrits dans les deux points précédents), les conditions suivantes doivent s’appliquer :

    • Le jeton d’ID doit être signé à l’aide de RS256 (vous pouvez définir cette valeur dans Dashboard > Clients > Réglages client > Réglages avancés > OAuth.

    • La demande aud du jeton d’ID doit identifier le client et avoir la même valeur que la demande azp du jeton d’accès.

  • Pour dissocier les comptes, vous ne pouvez plus utiliser de jeton d’ID à l’entête Authorization. Vous devez utiliser un jeton d’accès à la place.

Il existe plusieurs façons de lier et de dissocier des comptes. Dans la liste suivante, vous pouvez voir les cas d’utilisation et la façon dont les changements les affectent.

Cas d’utilisation État
Utilisez le point de terminaison de Management API POST /api/v2/users/{id}/identities et envoyez le jeton d’ID du compte principal dans l’en-tête Authorization. Affecté
Utilisez le point de terminaison de Management API POST /api/v2/users/{id}/identities et envoyez un jeton d’accès (avec la permission update:users) dans l’en-tête authorization et le user_id du compte secondaire dans la charge utile. Non affecté
Utilisez le point de terminaison de Management API POST /api/v2/users/{id}/identities et envoyez un jeton d’accès (avec la permission update:current_user_identities) dans l’en-tête Authorization et le user_id du compte secondaire dans la charge utile. Affecté
Utilisez le point de terminaison de Management API POST /api/v2/users/{id}/identities et envoyez un jeton d’accès dans l’en-tête Authorization et l’ID du compte secondaire dans la charge utile. Nouveau cas d’utilisation
Utilisez la bibliothèque auth0.js et le jeton d’ID du compte principal pour instancier auth0.Management. Affecté
Utilisez la bibliothèque auth0.js et un jeton d’accès (avec la permission update:users) pour instancier auth0.Management. Non affecté
Utilisez la bibliothèque auth0.js et un jeton d’accès (avec la permission update:current_user_identities) pour instancier auth0.Management. Affecté
Utilisez le point de terminaison de Management API DELETE /api/v2/users/{id}/identities/{provider}/{user_id} et envoyez le jeton d’ID du compte principal dans l’en-tête Authorization. Affecté
Utilisez le point de terminaison de Management API DELETE /api/v2/users/{id}/identities/{provider}/{user_id} et envoyez un jeton d’accès dans l’en-tête Authorization. Non affecté

Actions

Passez en revue tous vos appels au point de terminaison Identities d’association de comptes et mettez à jour ceux qui utilisent le flux vulnérable décrit ci-dessus. Vous pouvez mettre à jour vos requêtes en choisissant l’une des options suivantes :

  • Scénarios d’association côté client / à l’initiative de l’utilisateur : pour les scénarios d’association côté client, faites l’appel au point de terminaison Identities en utilisant un jeton d’accès avec la permission update:current_user_identities, et fournissez le jeton d’ID du compte secondaire dans la charge utile (link_with). Ce jeton d’ID doit être obtenu par un flux conforme à OAuth/OIDC.

  • Scénarios d’association côté serveur: pour les scénarios d’association côté serveur, appelez le point de terminaison Identities à l’aide d’un jeton d’accès avec la permission update:users et fournissez le user_id du compte secondaire dans la charge utile.

Consultez Associer des comptes d’utilisateurs pour obtenir plus de détails.

Associer des comptes d’utilisateurs

Pour associer des comptes d’utilisateurs, vous pouvez appeler le point de terminaison Associer un compte utilisateur de Management API ou utiliser la bibliothèque Auth0.js.

Associer des comptes d’utilisateurs actuels avec le Management API

Un cas d’utilisation courant consiste à permettre à l’utilisateur connecté d’associer ses comptes à l’aide de votre application.

Avant cette dépréciation, vous pouviez utiliser le jeton d’ID de l’utilisateur principal ou le jeton d’accès (qui contenait la permission update:current_user_identities) pour vous authentifier auprès de Management API et utiliser le point de terminaison Associer un compte utilisateur.

Désormais, vous devez obtenir un jeton d’accès (contenant la permission update:current_user_identities) et l’utiliser pour vous authentifier auprès de l’API et utiliser le point de terminaison Associer un compte utilisateur. Les données utiles doivent être le jeton d’ID de l’utilisateur secondaire.

  1. Obtenez un jeton d’accès avec la permission update:current_user_identities comme le montre l’exemple suivant. L’exemple utilise le flux implicite, mais vous pouvez obtenir des jetons d’accès pour n’importe quel type d’application.

  2. En utilisant la méthode précédente avec un jeton d’ID, votre code ressemblerait à ceci :

    codeblockOld.header.login.configureSnippet
    https://{yourDomain}/authorize?
          scope=openid
          &response_type=id_token
          &client_id={yourClientId}
          &redirect_uri=https://{yourApp}/callback
          &nonce=NONCE
          &state=OPAQUE_VALUE

    Was this helpful?

    /
    En utilisant la nouvelle méthode avec un jeton d’accès, votre code ressemblera à ceci :
    codeblockOld.header.login.configureSnippet
    https://{yourDomain}/authorize?
          audience=https://{yourDomain}/api/v2/
          &scope=update:current_user_identities
          &response_type=token%20id_token
          &client_id={yourClientId}
          &redirect_uri=https://{yourApp}/callback
          &nonce={nonce}
          &state={opaqueValue}

    Was this helpful?

    /

  3. Pour obtenir un jeton d’accès à Management API :

    1. Définir audience à https://{yourDomain}/api/v2/.

    2. Demandez la scope${scope}.

    3. Définissez le response_type à id_token token pour que Auth0 envoie à la fois un jeton d’ID et un jeton d’accès. Si nous décodons le jeton d’accès et examinons son contenu, nous constatons ce qui suit :

      {
            "iss": "https://{yourDomain}/",
            "sub": "auth0|5a620d29a840170a9ef43672",
            "aud": "https://{yourDomain}/api/v2/",
            "iat": 1521031317,
            "exp": 1521038517,
            "azp": "{yourClientId}",
            "scope": "${scope}"
          }

      Was this helpful?

      /
      Remarquez que aud est défini sur l’URI de l’API de votre locataire, scope sur ${scope}, et sub sur l’identifiant de l’utilisateur connecté.

  4. Les conditions suivantes doivent être remplies :

    1. Le jeton d’ID du compte secondaire doit être signé avec RS256.

    2. La demande aud dans le jeton d’ID du compte secondaire doit identifier le client et avoir la même valeur que la demande azp du jeton d’accès utilisé pour effectuer la demande.

  5. Une fois que vous avez le jeton d’accès, vous pouvez l’utiliser pour associer des comptes d’utilisateurs. Cette partie reste inchangée, rien d’autre ne change dans la demande, à l’exception de la valeur utilisée comme jeton Bearer. La réponse reste également la même.

    {
          "method": "POST",
          "url": "https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities",
          "httpVersion": "HTTP/1.1",
          "headers": [{
          "name": "Authorization",
          "value": "Bearer ACCESS_TOKEN"
          },
          {
          "name": "content-type",
          "value": "application/json"
          }],
          "postData" : {
          "mimeType": "application/json",
          "text": "{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}"
          }
        }

    Was this helpful?

    /

Associer les comptes utilisateurs actuels avec auth0.js

Si vous utilisez la bibliothèque auth0.js pour accéder à Management API et associer des comptes, vous utilisez probablement le jeton d’ID de l’identité principale de l’utilisateur pour instancier auth0.Management et l’utiliser pour associer des comptes.

  1. Obtenez un jeton d’accès avec la permission update:current_user_identities, puis utilisez ce jeton pour instancier auth0.Management. L’appel final à linkUserreste inchangé.

  2. En utilisant la méthode précédente avec un jeton d’ID, votre code ressemblerait à ceci :

    codeblockOld.header.login.configureSnippet
    // get an ID Token
        var webAuth = new auth0.WebAuth({
          clientID: '{yourClientId}',
          domain: '{yourDomain}',
          redirectUri: 'https://{yourApp}/callback',
          scope: 'openid',
          responseType: 'id_token'
        });
        // create a new instance
        var auth0Manage = new auth0.Management({
          domain: '{yourDomain}',
          token: '{yourIdToken}'
        });

    Was this helpful?

    /
    En utilisant la nouvelle méthode avec un jeton d’accès, votre code ressemblera à ceci :
    codeblockOld.header.login.configureSnippet
    // get an Access Token
        var webAuth = new auth0.WebAuth({
          clientID: '{yourClientId}',
          domain: '{yourDomain}',
          redirectUri: 'https://{yourApp}/callback',
          audience: 'https://{yourDomain}/api/v2/',
          scope: 'update:current_user_identities',
          responseType: 'token id_token'
        });
        // create a new instance
        var auth0Manage = new auth0.Management({
          domain: '{yourDomain}',
          token: '{yourMgmtApiAccessToken}'
        });

    Was this helpful?

    /

    1. Demande un jeton d’ID et un jeton d’accès en réponse (responseType: `token id_token`).

    2. Définit Management API comme public cible du jeton (audience: `https://{yourDomain}/api/v2/`).

    3. Demande la permission requise (scope: `update:current_user_identities`).

    4. S’authentifie auprès de Management API à l’aide du jeton d’accès.

Associer n’importe quel compte d’utilisateur à Management API

Si vous obtenez un jeton d’accès pour l’association de comptes qui contient la permission update:users, et que vous envoyez le user_id et le provider du compte secondaire dans la requête, vous n’avez pas besoin d’effectuer de modifications.

Toutefois, cette nouvelle méthode offre une alternative. Vous utiliserez toujours un jeton d’accès contenant la permission update:users pour vous authentifier auprès de l’API, mais dans la charge utile de la demande, vous pouvez envoyer le jeton d’ID du compte secondaire (au lieu du user_id et du provider).


curl --request POST \
  --url 'https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities' \
  --header 'authorization: Bearer ACCESS_TOKEN' \
  --header 'content-type: application/json' \
  --data '{"link_with":"SECONDARY_ACCOUNT_ID_TOKEN"}'

Was this helpful?

/
var client = new RestClient("https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer ACCESS_TOKEN");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Was this helpful?

/
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities"

	payload := strings.NewReader("{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("authorization", "Bearer ACCESS_TOKEN")
	req.Header.Add("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Was this helpful?

/
HttpResponse<String> response = Unirest.post("https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities")
  .header("authorization", "Bearer ACCESS_TOKEN")
  .header("content-type", "application/json")
  .body("{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}")
  .asString();

Was this helpful?

/
var axios = require("axios").default;

var options = {
  method: 'POST',
  url: 'https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities',
  headers: {authorization: 'Bearer ACCESS_TOKEN', 'content-type': 'application/json'},
  data: {link_with: 'SECONDARY_ACCOUNT_ID_TOKEN'}
};

axios.request(options).then(function (response) {
  console.log(response.data);
}).catch(function (error) {
  console.error(error);
});

Was this helpful?

/
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer ACCESS_TOKEN",
                           @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"link_with": @"SECONDARY_ACCOUNT_ID_TOKEN" };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];

Was this helpful?

/
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}",
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer ACCESS_TOKEN",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

Was this helpful?

/
import http.client

conn = http.client.HTTPSConnection("")

payload = "{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}"

headers = {
    'authorization': "Bearer ACCESS_TOKEN",
    'content-type': "application/json"
    }

conn.request("POST", "/{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))

Was this helpful?

/
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer ACCESS_TOKEN'
request["content-type"] = 'application/json'
request.body = "{\"link_with\":\"SECONDARY_ACCOUNT_ID_TOKEN\"}"

response = http.request(request)
puts response.read_body

Was this helpful?

/
import Foundation

let headers = [
  "authorization": "Bearer ACCESS_TOKEN",
  "content-type": "application/json"
]
let parameters = ["link_with": "SECONDARY_ACCOUNT_ID_TOKEN"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Was this helpful?

/

Les conditions suivantes doivent être remplies :

  • Le jeton d’ID du compte secondaire doit être signé avec RS256.

  • La demande aud dans le jeton d’ID du compte secondaire doit identifier le client et avoir la même valeur que la demande azp du jeton d’accès utilisé pour effectuer la demande.

Désassocier des comptes d’utilisateurs

Si vous utilisez des jetons d’ID pour dissocier des comptes, vous devez mettre à jour votre code pour utiliser des jetons d’accès.

  1. Tout d’abord, vous devez obtenir un jeton d’accès avec la permission update:current_user_identities.

  2. En utilisant la méthode précédente avec un jeton d’ID, votre code ressemblerait à ceci :

    codeblockOld.header.login.configureSnippet
    https://{yourDomain}/authorize?
          scope=openid
          &response_type=id_token
          &client_id={yourClientId}
          &redirect_uri=https://{yourApp}/callback
          &nonce={nonce}
          &state={opaqueValue}

    Was this helpful?

    /
    En utilisant la nouvelle méthode avec un jeton d’accès, votre code ressemblera à ceci :
    codeblockOld.header.login.configureSnippet
    https://{yourDomain}/authorize?
          audience=https://{yourDomain}/api/v2/
          &scope=update:current_user_identities
          &response_type=token%20id_token
          &client_id={yourClientId}
          &redirect_uri=https://{yourApp}/callback
          &nonce={nonce}
          &state={opaqueValue}

    Was this helpful?

    /

  3. Pour obtenir un jeton d’accès à Management API :

    1. Définir audience à https://{yourDomain}/api/v2/.

    2. Demandez la scope${scope}.

    3. Définissez le response_type à id_token token pour que Auth0 envoie à la fois un jeton d’ID et un jeton d’accès. Si nous décodons le jeton d’accès et examinons son contenu, nous constatons ce qui suit :

      codeblockOld.header.login.configureSnippet
      {
            "iss": "https://{yourDomain}/",
            "sub": "auth0|5a620d29a840170a9ef43672",
            "aud": "https://{yourDomain}/api/v2/",
            "iat": 1521031317,
            "exp": 1521038517,
            "azp": "{yourClientId}",
            "scope": "update:current_user_identities"
          }

      Was this helpful?

      /
      Notez que aud est défini sur l’URI de l’API de votre locataire, scope sur update:current_user_identities, et sub sur l’identifiant de l’utilisateur connecté.

  4. Une fois que vous avez le jeton d’accès, vous pouvez appeler le point de terminaison Dissocier l’identité d’un utilisateur de Management API, en l’utilisant dans l’en-tête Autorisation.

  5. En utilisant la méthode précédente, votre requête ressemblera à ceci :

    DELETE https://YOUR_DOMAIN/api/v2/users/{primaryAccountUserId}/identities/{secondaryAccountProvider}/{secondaryAccountUserId}
        Authorization: 'Bearer {yourIdTokenOrMgmtApiAccessToken}'

    Was this helpful?

    /
    En utilisant la nouvelle méthode, votre requête ressemblera à ceci :
    DELETE https://{yourDomain}/api/v2/users/{primaryAccountUserId}/identities/{secondaryAccountProvider}/{secondaryAccountUserId}
        Authorization: 'Bearer {yourMgmtApiAccessToken}'

    Was this helpful?

    /

Considérations relatives à la sécurité

Nous avons identifié une faiblesse dans le flux de liaison d’un compte particulier qui pourrait permettre de l’utiliser à mauvais escient dans des circonstances spécifiques. Nous n’avons trouvé aucune preuve que cela ait été utilisé de manière malveillante, mais nous avons décidé de déprécier le flux pour éviter que cela ne se produise.

Par conséquent, Auth0 demande aux clients qui utilisent le flux de liaison de compte affecté de migrer vers une implémentation plus sécurisée avant le 19 octobre 2018. Le présent guide fournit des pistes de migration qui ne devraient pas entraîner de perte de fonctionnalité.

À partir du 19 octobre 2018, le flux de liaison des comptes concernés sera désactivé et des erreurs d’exécution se produiront.

Vous êtes concerné si vous appelez le point de terminaison Post Identities en utilisant un jeton (identifiant ou jeton d’accès) avec la permission update:current_user_identities dans l’en-tête Authorization et que vous incluez le user_id du compte secondaire dans la charge utile. Aucun autre cas d’utilisation n’est affecté.

En savoir plus