User Consent and Third-Party Applications (Consentement de l’utilisateur et applications tierces)

Le pipeline d’authentification conforme à l’OIDC prend charge la définition des serveurs de ressources (tels que les API) en tant qu’entités distinctes des applications. Cela vous permet de découpler les API des applications qui les consomment, et vous permet également de définir des applications tierces permettant à des tiers d’accéder en toute sécurité à des ressources protégées derrière votre API.

Dialogue sur le consentement

Si un utilisateur s’authentifie par l’intermédiaire d’une application tierce et que l’application demande l’autorisation d’accéder aux informations de l’utilisateur ou d’effectuer une action en son nom au niveau d’une API, l’utilisateur verra s’afficher une boîte de dialogue de consentement.

Par exemple, cette demande :

GET /authorize?
client_id=some_third_party_client
&redirect_uri=https://fabrikam.com/contoso_social
&response_type=token id_token
&__scope=openid profile email read:posts write:posts__
&__audience=https://social.contoso.com__
&nonce=...
&state=...

Was this helpful?

/

Le dialogue de consentement de l’utilisateur s’affiche :

Authorization (Autorisation) - User consent and applications (Applications et consentement utilisateur) - consent-dialog (Dialogue de consentement)

Si l’utilisateur autorise la demande de l’application, cela crée une autorisation de l’utilisateur, laquelle représente le consentement de l’utilisateur à cette combinaison d’application, de serveur de ressources et de permissions demandées. L’application reçoit alors une réponse d’authentification réussie de la part d’Auth0, comme d’habitude.

Une fois le consentement donné, l’utilisateur ne verra plus la boîte de dialogue de consentement lors des connexions suivantes, jusqu’à ce qu’il révoque explicitement son consentement.

Description du permission

Par défaut, la page de consentement utilisera les noms des champs d’application pour demander le consentement de l’utilisateur. Comme indiqué ci-dessous, vous devez définir les permissions à l’aide du format action:resource_name.

Authorization (Autorisation) - User consent and applications (Applications et consentement utilisateur) - Consent scopes (Champs d’application du consentement)

La page de consentement regroupe les permissions d’une même ressource et affiche toutes les actions relatives à cette ressource sur une seule ligne. Par exemple, la configuration ci-dessus se traduirait par Messages : consultez et écrivez vos messages.

Si vous souhaitez afficher le champ Description à la place, vous pouvez le faire en définissant le champ use_scope_descriptions_for_consent sur true. Cela affectera les invites de consentement pour toutes les API de ce locataire.

Pour définir l’indicateur use_scope_descriptions_for_consent vous devrez faire la requête appropriée à l’API :


curl --request PATCH \
  --url 'https://{yourDomain}/api/v2/tenants/settings' \
  --header 'authorization: Bearer API2_ACCESS_TOKEN' \
  --header 'cache-control: no-cache' \
  --header 'content-type: application/json' \
  --data '{ "flags": { "use_scope_descriptions_for_consent": true } }'

Was this helpful?

/
var client = new RestClient("https://{yourDomain}/api/v2/tenants/settings");
var request = new RestRequest(Method.PATCH);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer API2_ACCESS_TOKEN");
request.AddHeader("cache-control", "no-cache");
request.AddParameter("application/json", "{ \"flags\": { \"use_scope_descriptions_for_consent\": true } }", 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/tenants/settings"

	payload := strings.NewReader("{ \"flags\": { \"use_scope_descriptions_for_consent\": true } }")

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

	req.Header.Add("content-type", "application/json")
	req.Header.Add("authorization", "Bearer API2_ACCESS_TOKEN")
	req.Header.Add("cache-control", "no-cache")

	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.patch("https://{yourDomain}/api/v2/tenants/settings")
  .header("content-type", "application/json")
  .header("authorization", "Bearer API2_ACCESS_TOKEN")
  .header("cache-control", "no-cache")
  .body("{ \"flags\": { \"use_scope_descriptions_for_consent\": true } }")
  .asString();

Was this helpful?

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

var options = {
  method: 'PATCH',
  url: 'https://{yourDomain}/api/v2/tenants/settings',
  headers: {
    'content-type': 'application/json',
    authorization: 'Bearer API2_ACCESS_TOKEN',
    'cache-control': 'no-cache'
  },
  data: {flags: {use_scope_descriptions_for_consent: true}}
};

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 = @{ @"content-type": @"application/json",
                           @"authorization": @"Bearer API2_ACCESS_TOKEN",
                           @"cache-control": @"no-cache" };
NSDictionary *parameters = @{ @"flags": @{ @"use_scope_descriptions_for_consent": @YES } };

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

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/api/v2/tenants/settings"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[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/tenants/settings",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PATCH",
  CURLOPT_POSTFIELDS => "{ \"flags\": { \"use_scope_descriptions_for_consent\": true } }",
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer API2_ACCESS_TOKEN",
    "cache-control: no-cache",
    "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 = "{ \"flags\": { \"use_scope_descriptions_for_consent\": true } }"

headers = {
    'content-type': "application/json",
    'authorization': "Bearer API2_ACCESS_TOKEN",
    'cache-control': "no-cache"
    }

conn.request("PATCH", "/{yourDomain}/api/v2/tenants/settings", 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/tenants/settings")

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

request = Net::HTTP::Patch.new(url)
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer API2_ACCESS_TOKEN'
request["cache-control"] = 'no-cache'
request.body = "{ \"flags\": { \"use_scope_descriptions_for_consent\": true } }"

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

Was this helpful?

/
import Foundation

let headers = [
  "content-type": "application/json",
  "authorization": "Bearer API2_ACCESS_TOKEN",
  "cache-control": "no-cache"
]
let parameters = ["flags": ["use_scope_descriptions_for_consent": true]] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/api/v2/tenants/settings")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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?

/

Traiter les autorisations rejetées

Si un utilisateur décide de refuser le consentement à l’application, il sera redirigé vers le redirect_uri spécifié dans la demande avec une erreur access_denied :

HTTP/1.1 302 Found
Location: https://fabrikam.com/contoso_social#
    error=access_denied
    &state=...

Was this helpful?

/

Ignorer le consentement pour les applications de première partie

Les applications de première partie peuvent ignorer la boîte de dialogue de consentement, mais uniquement si l’API à laquelle elles tentent d’accéder au nom de l’utilisateur dispose de l’option Permettre d’ignorer le consentement de l’utilisateur.

Pour naviguer jusqu’à la bascule Permettre d’ignorer le consentement de l’utilisateur , sélectionnez Applications > API > (sélectionnez l’API) > Paramètres > Paramètres d’accès.

Consentement de l’utilisateur et applications

Remarque : cette option permet aux applications de première partie vérifiables d’ignorer le consentement. Compte tenu que localhost n’est jamais une première partie vérifiable (car des applications malveillantes peuvent s’exécuter sur localhost pour un utilisateur), Auth0 affichera toujours un dialogue de consentement pour les applications s’exécutant sur localhost, peu importe si elles sont marquées ou non comme applications de première partie. Au cours du développement, vous pouvez contourner cette limitation en modifiant votre fichier /etc/hosts en y ajoutant une entrée comme suit :

127.0.0.1 myapp.example

De la même façon, vous ne pouvez pas ignorer le consentement (même pour les applications première partie) si localhost apparaît dans n’importe quel domaine dans le paramètre URL de rappel autorisées dans Dashboard > Applications > Settings (Paramètres). Assurez-vous de mettre à jour les URL de rappel autorisées et l’URL de rappel autorisée dans votre application pour correspondre au mapping du domaine mis à jour.

Puisque les applications tierces sont jugées ne pas être fiables, elles ne peuvent pas ignorer les boîtes de dialogue de consentement.

Révoquer le consentement

Si un utilisateur a donné son consentement mais que vous souhaitez le révoquer :

  1. Accédez à Auth0 Dashboard > Gestion des utilisateurs > Utilisateurs, et cliquez sur l’utilisateur pour lequel vous souhaitez révoquer le consentement.

  2. Cliquez sur l’onglet Applications autorisées,

  3. Cliquez sur Révoquer à côté de l’application.

Flux basés sur un mot de passe

Lors de l’utilisation du Flux de mot de passe du propriétaire de ressource, il n’y a pas de dialogue de consentement car l’utilisateur fournit directement son mot de passe à l’application, ce qui équivaut à accorder à l’application un accès complet au compte de l’utilisateur.

Obliger les utilisateurs à donner leur consentement

Lors de la redirection vers le point de terminaison /authorize, l’inclusion du paramètre prompt=consent obligera les utilisateurs à donner leur consentement, même s’ils disposent déjà d’une autorisation d’accès à l’application et aux permissions demandées.

En savoir plus