User Impersonation

Often administrators need to impersonate other users for testing or troubleshooting purposes. Using impersonation the administrators can login to an app as a specific user, see everything exactly as that user sees it, and do everything exactly as that user does it.

Auth0 provides a Sign in As feature for user impersonation, and provides the following:

  • Detailed auditing of who impersonated when.
  • Restrictions on impersonation which allows you to reject an impersonated authentication transaction based on, for instance, corporate policies around privacy and sensitive data.
  • Unlimited customization on who can impersonate who, when, depending on whatever context, using our Rules engine. In a Rule, you have access to user.impersonated (the impersonated login) and user.impersonator (the impersonating login) and you can write arbitrary Javascript to define how it works.

Impersonate a User using the Management Dashboard

Navigate to the Users page in the Management Dashboard and select the user you want to login as. Click on the Sign in as User and select the app you want to log into using the dropdown menu.

Can't see the button? Check the following conditions; they should apply for the button to be displayed:

  • The applications registered in the account must have at least one callback URL listed.
  • The applications must have the connections turned on that the users who are to be impersonated belong to.

A popup displays the URL to be used in order to impersonate the user. You can choose either to copy the URL into the clipboard (white button) or open it in a separate browser tab/window (blue button).

Impersonating a user using the Management Dashboard will not return a JWT to your application by default. You can achieve this by calling the impersonation endpoint manually and adding additionalParameters.scope: "openid" to the request body.

Impersonate a User using the Impersonation API

You can also use the Impersonation API. The API generates a link that can be used once to log in as a specific user. To distinguish between real logins and impersonation logins, the profile of the impersonated user will contain additional impersonated and impersonator properties. For more details on how to use the API read on.

Implement impersonation in your app

Let's assume that you have two apps, app1 and app2, and you want to impersonate the users of app2.

Your first step would be to generate a Bearer token to be used with Impersonation API. You can generate it with the Authentication API /oauth/token endpoint using your Global Client ID and Global Client Secret. The token will be valid for 24 hours, so you should ask for a token everytime you make a request to the API or handle vigorously 401 responses.


curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN/oauth/token' \
  --header 'content-type: application/json' \
  --data '{"client_id": "YOUR_CLIENT_ID","client_secret": "YOUR_CLIENT_SECRET","grant_type": "client_credentials"}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/oauth/token");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"grant_type\": \"client_credentials\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

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

func main() {

	url := "https://YOUR_AUTH0_DOMAIN/oauth/token"

	payload := strings.NewReader("{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"grant_type\": \"client_credentials\"}")

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

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

}
HttpResponse<String> response = Unirest.post("https://YOUR_AUTH0_DOMAIN/oauth/token")
  .header("content-type", "application/json")
  .body("{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"grant_type\": \"client_credentials\"}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN/oauth/token",
  "method": "POST",
  "headers": {
    "content-type": "application/json"
  },
  "processData": false,
  "data": "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"grant_type\": \"client_credentials\"}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://YOUR_AUTH0_DOMAIN/oauth/token',
  headers: { 'content-type': 'application/json' },
  body: 
   { client_id: 'YOUR_CLIENT_ID',
     client_secret: 'YOUR_CLIENT_SECRET',
     grant_type: 'client_credentials' },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"client_id": @"YOUR_CLIENT_ID",
                              @"client_secret": @"YOUR_CLIENT_SECRET",
                              @"grant_type": @"client_credentials" };

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

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/oauth/token"]
                                                       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];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN/oauth/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"grant_type\": \"client_credentials\"}",
  CURLOPT_HTTPHEADER => array(
    "content-type: application/json"
  ),
));

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

curl_close($curl);

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

conn = http.client.HTTPSConnection("")

payload = "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"grant_type\": \"client_credentials\"}"

headers = { 'content-type': "application/json" }

conn.request("POST", "/YOUR_AUTH0_DOMAIN/oauth/token", payload, headers)

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

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN/oauth/token")

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["content-type"] = 'application/json'
request.body = "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"grant_type\": \"client_credentials\"}"

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

let headers = ["content-type": "application/json"]
let parameters = [
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET",
  "grant_type": "client_credentials"
]

let postData = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: nil)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/oauth/token")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

Management APIv2 calls are made with tokens issued by your Global Client ID, which is a unique identifier for your Auth0 account. You can retrieve your Global Client ID and Global Client Secret in the Management APIv2 documentation page (click on API Key/Secret). They are also available at the Advanced section under Account Settings in the Auth0 Management Dashboard.

Afterwards, you would have to find out the user id of the user that you want to impersonate. That would be the user of app2. You can retrieve this information with the Management API /api/v2/users endpoint.


curl --request GET \
  --url 'https://YOUR_AUTH0_DOMAIN/api/v2/users' \
  --header 'authorization: Bearer {bearer-token}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/api/v2/users");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {bearer-token}");
IRestResponse response = client.Execute(request);
package main

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

func main() {

	url := "https://YOUR_AUTH0_DOMAIN/api/v2/users"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("authorization", "Bearer {bearer-token}")

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

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

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

}
HttpResponse<String> response = Unirest.get("https://YOUR_AUTH0_DOMAIN/api/v2/users")
  .header("authorization", "Bearer {bearer-token}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN/api/v2/users",
  "method": "GET",
  "headers": {
    "authorization": "Bearer {bearer-token}"
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://YOUR_AUTH0_DOMAIN/api/v2/users',
  headers: { authorization: 'Bearer {bearer-token}' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer {bearer-token}" };

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/api/v2/users"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];

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];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN/api/v2/users",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "authorization: Bearer {bearer-token}"
  ),
));

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

curl_close($curl);

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

conn = http.client.HTTPSConnection("")

headers = { 'authorization': "Bearer {bearer-token}" }

conn.request("GET", "/YOUR_AUTH0_DOMAIN/api/v2/users", headers=headers)

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

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN/api/v2/users")

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

request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer {bearer-token}'

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

let headers = ["authorization": "Bearer {bearer-token}"]

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/api/v2/users")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "GET"
request.allHTTPHeaderFields = headers

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

The {bearer_token} should be replaced with an Auth0 Management APIv2 token. Details on how to do this can be found here.

You can also retrieve the user_id information from the Management Dashboard. Go to the Users section and look at the user’s profile. The user_id is displayed under the Identity Provider Attributes section.

You are now ready to call the Impersonation API. The request should include an Authorization header with Bearer bearer-token, where bearer-token is the token you retrieved at the first step. The data part of the request should include the following:

  • protocol: the protocol to use against the identity provider. It could be oauth2 again or something else. (e.g. Office 365 uses WS-Federation, Google Apps uses OAuth2, AD will use LDAP or Kerberos).
  • impersonator_id: the user_id of the impersonator, the user from app1 that wants to impersonate a user from app2.
  • client_id: the client_id of the app that is generating the impersonation link, in this example app1.
  • additionalParameters: this is a JSON object. For a regular web app, you should set the response_type to be code, the callback_url to be the callback url to which Auth0 will redirect with the authorization code, and the scope to be the JWT claims that you want included in the JWT. For example:
"response_type": "code",
"state": "",
"callback_url" : "http://localhost:3001/register",
"scope" : "openid email name user_metadata"

The state is an optional parameter, but we strongly recommend you use it as it mitigates CSRF attacks.

The callback_url must match what is defined in your settings page.

There are various possible values for scope:

  • scope: 'openid': (default) It will return, not only the access_token, but also an id_token which is a _JSON Web Token (JWT). The JWT will only contain the user id (sub claim).
  • scope: 'openid {attr1} {attr2} {attrN}': If you want only specific user's attributes to be part of the id_token (For example: scope: 'openid name email picture'). You can get more information about this in the Scopes documentation.

curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate' \
  --header 'authorization: Bearer {bearer-token}' \
  --header 'content-type: application/json' \
  --data '{"protocol": "{protocol-to-use}","impersonator_id": "{impersonator-id}","client_id": "YOUR_CLIENT_ID","additionalParameters":{"response_type": "code","state": ""}}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {bearer-token}");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"protocol\": \"{protocol-to-use}\",\"impersonator_id\": \"{impersonator-id}\",\"client_id\": \"YOUR_CLIENT_ID\",\"additionalParameters\":{\"response_type\": \"code\",\"state\": \"\"}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

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

func main() {

	url := "https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate"

	payload := strings.NewReader("{\"protocol\": \"{protocol-to-use}\",\"impersonator_id\": \"{impersonator-id}\",\"client_id\": \"YOUR_CLIENT_ID\",\"additionalParameters\":{\"response_type\": \"code\",\"state\": \"\"}}")

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

	req.Header.Add("content-type", "application/json")
	req.Header.Add("authorization", "Bearer {bearer-token}")

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

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

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

}
HttpResponse<String> response = Unirest.post("https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate")
  .header("content-type", "application/json")
  .header("authorization", "Bearer {bearer-token}")
  .body("{\"protocol\": \"{protocol-to-use}\",\"impersonator_id\": \"{impersonator-id}\",\"client_id\": \"YOUR_CLIENT_ID\",\"additionalParameters\":{\"response_type\": \"code\",\"state\": \"\"}}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate",
  "method": "POST",
  "headers": {
    "content-type": "application/json",
    "authorization": "Bearer {bearer-token}"
  },
  "processData": false,
  "data": "{\"protocol\": \"{protocol-to-use}\",\"impersonator_id\": \"{impersonator-id}\",\"client_id\": \"YOUR_CLIENT_ID\",\"additionalParameters\":{\"response_type\": \"code\",\"state\": \"\"}}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate',
  headers: 
   { authorization: 'Bearer {bearer-token}',
     'content-type': 'application/json' },
  body: 
   { protocol: '{protocol-to-use}',
     impersonator_id: '{impersonator-id}',
     client_id: 'YOUR_CLIENT_ID',
     additionalParameters: { response_type: 'code', state: '' } },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"content-type": @"application/json",
                           @"authorization": @"Bearer {bearer-token}" };
NSDictionary *parameters = @{ @"protocol": @"{protocol-to-use}",
                              @"impersonator_id": @"{impersonator-id}",
                              @"client_id": @"YOUR_CLIENT_ID",
                              @"additionalParameters": @{ @"response_type": @"code", @"state": @"" } };

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

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate"]
                                                       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];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"protocol\": \"{protocol-to-use}\",\"impersonator_id\": \"{impersonator-id}\",\"client_id\": \"YOUR_CLIENT_ID\",\"additionalParameters\":{\"response_type\": \"code\",\"state\": \"\"}}",
  CURLOPT_HTTPHEADER => array(
    "authorization: Bearer {bearer-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;
}
import http.client

conn = http.client.HTTPSConnection("")

payload = "{\"protocol\": \"{protocol-to-use}\",\"impersonator_id\": \"{impersonator-id}\",\"client_id\": \"YOUR_CLIENT_ID\",\"additionalParameters\":{\"response_type\": \"code\",\"state\": \"\"}}"

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

conn.request("POST", "/YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate", payload, headers)

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

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate")

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["content-type"] = 'application/json'
request["authorization"] = 'Bearer {bearer-token}'
request.body = "{\"protocol\": \"{protocol-to-use}\",\"impersonator_id\": \"{impersonator-id}\",\"client_id\": \"YOUR_CLIENT_ID\",\"additionalParameters\":{\"response_type\": \"code\",\"state\": \"\"}}"

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

let headers = [
  "content-type": "application/json",
  "authorization": "Bearer {bearer-token}"
]
let parameters = [
  "protocol": "{protocol-to-use}",
  "impersonator_id": "{impersonator-id}",
  "client_id": "YOUR_CLIENT_ID",
  "additionalParameters": [
    "response_type": "code",
    "state": ""
  ]
]

let postData = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: nil)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

Replace the required values as follows:

  • The {user_id} should be replaced with the user_id you retrieved at the second step (the user to impersonate).
  • The {bearer_token} should be replaced with the token already retrieved at the first step.
  • The {protocol-to-use} should be replaced with the protocol to use against the identity provider, for example oauth2.
  • The {impersonator-id} should be replaced with the user_id of the impersonator.

Upon successful authentication, a URL will be returned as response that will look like the following:

https://YOUR_APP/callback/?code=AUTHORIZATION_CODE&state=STATE_VALUE

https://YOUR_APP/callback is the URL you specified as callback_url (and configured in your settings page), state should match the state value you sent with your request and code is the authorization code you need.

The process described applies to Regular Web Applications. In case yours is a Single Page Application (SPA) you would have to use "response_type":"token" when invoking the Impersonation API. Once you do this Auth0 will redirect to your SPA Callback URL with access_token and id_token in the # params. You can read more on the OAuth2 Implicit flow here.

Now you should exchange the code you received for a token. Note that this should already be implemented if you have a regular webapp and are using OAuth Server Side flow for authenticating normal users.

If not you should send a POST request to the token endpoint in Auth0. You will need to send the code obtained before along with your clientId and clientSecret.


curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN/users/oauth/token' \
  --header 'content-type: application/json' \
  --data '{"client_id": "YOUR_CLIENT_ID","client_secret": "YOUR_CLIENT_SECRET","code": "{AUTHORIZATION_CODE}","grant_type": "authorization_code","callback_url": "{CALLBACK_URL}"}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/users/oauth/token");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"{AUTHORIZATION_CODE}\",\"grant_type\": \"authorization_code\",\"callback_url\": \"{CALLBACK_URL}\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

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

func main() {

	url := "https://YOUR_AUTH0_DOMAIN/users/oauth/token"

	payload := strings.NewReader("{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"{AUTHORIZATION_CODE}\",\"grant_type\": \"authorization_code\",\"callback_url\": \"{CALLBACK_URL}\"}")

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

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

}
HttpResponse<String> response = Unirest.post("https://YOUR_AUTH0_DOMAIN/users/oauth/token")
  .header("content-type", "application/json")
  .body("{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"{AUTHORIZATION_CODE}\",\"grant_type\": \"authorization_code\",\"callback_url\": \"{CALLBACK_URL}\"}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN/users/oauth/token",
  "method": "POST",
  "headers": {
    "content-type": "application/json"
  },
  "processData": false,
  "data": "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"{AUTHORIZATION_CODE}\",\"grant_type\": \"authorization_code\",\"callback_url\": \"{CALLBACK_URL}\"}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://YOUR_AUTH0_DOMAIN/users/oauth/token',
  headers: { 'content-type': 'application/json' },
  body: 
   { client_id: 'YOUR_CLIENT_ID',
     client_secret: 'YOUR_CLIENT_SECRET',
     code: '{AUTHORIZATION_CODE}',
     grant_type: 'authorization_code',
     callback_url: '{CALLBACK_URL}' },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"client_id": @"YOUR_CLIENT_ID",
                              @"client_secret": @"YOUR_CLIENT_SECRET",
                              @"code": @"{AUTHORIZATION_CODE}",
                              @"grant_type": @"authorization_code",
                              @"callback_url": @"{CALLBACK_URL}" };

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

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/users/oauth/token"]
                                                       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];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN/users/oauth/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"{AUTHORIZATION_CODE}\",\"grant_type\": \"authorization_code\",\"callback_url\": \"{CALLBACK_URL}\"}",
  CURLOPT_HTTPHEADER => array(
    "content-type: application/json"
  ),
));

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

curl_close($curl);

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

conn = http.client.HTTPSConnection("")

payload = "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"{AUTHORIZATION_CODE}\",\"grant_type\": \"authorization_code\",\"callback_url\": \"{CALLBACK_URL}\"}"

headers = { 'content-type': "application/json" }

conn.request("POST", "/YOUR_AUTH0_DOMAIN/users/oauth/token", payload, headers)

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

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN/users/oauth/token")

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["content-type"] = 'application/json'
request.body = "{\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"{AUTHORIZATION_CODE}\",\"grant_type\": \"authorization_code\",\"callback_url\": \"{CALLBACK_URL}\"}"

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

let headers = ["content-type": "application/json"]
let parameters = [
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET",
  "code": "{AUTHORIZATION_CODE}",
  "grant_type": "authorization_code",
  "callback_url": "{CALLBACK_URL}"
]

let postData = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: nil)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/users/oauth/token")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

Replace the {AUTHORIZATION_CODE} with the code you received previously. Also, replace {CALLBACK_URL} with your application's callback URL.

If the request is successful, you will get a JSON object with an access_token. You can use this token to call the Auth0 APIs and get additional information such as the user profile.

Sample Access Token Response:

{ "access_token": ".....Access Token.....", "token_type": "bearer", "id_token": "......The JWT......" }

Congratulations, you are done!

Further reading