PingOne Platform APIs

Token Exchange (Gateway Credential)

POST {{authPath}}/{{envID}}/as/token

The token endpoint can be used by the client to make a token exchange request to the PingOne authorization server by presenting its authorization grant, its token, and the token type. For a token exchange operation, the grant_type must be set to urn:ietf:params:oauth:grant-type:token-exchange.

The subject_token property value is the gateway credential returned by the PingOne gateway service. For more information, refer to Gateway Credentials.

The PingOne authorization server’s token endpoint responds to a successful token exchange request by issuing an access token that allows the requesting client access to PingOne resources.

Any valid gateway credential can be exchanged for an access token. The access token returned by the exchange will have a five-minute time to live.

Prerequisites

Request Model
Property Type Required?

subject_token_type

String

Required

subject_token

String

Required

grant_type

String

Required

Refer to the OpenID Connect/OAuth2 data model for full property descriptions.

Headers

Authorization

Content-Type      application/x-www-form-urlencoded

Body

urlencoded ( application/x-www-form-urlencoded )

Key Value

grant_type

urn:ietf:params:oauth:grant-type:token-exchange

subject_token_type

pingone_gateway_credential

subject_token

{{gatewayCredential}}

Example Request

  • cURL

  • C#

  • Go

  • HTTP

  • Java

  • jQuery

  • NodeJS

  • Python

  • PHP

  • Ruby

  • Swift

curl --location --globoff '{{authPath}}/{{envID}}/as/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'subject_token_type=pingone_gateway_credential' \
--data-urlencode 'subject_token={{gatewayCredential}}'
var options = new RestClientOptions("{{authPath}}/{{envID}}/as/token")
{
  MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Authorization", "Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19");
request.AddParameter("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange");
request.AddParameter("subject_token_type", "pingone_gateway_credential");
request.AddParameter("subject_token", "{{gatewayCredential}}");
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
package main

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

func main() {

  url := "{{authPath}}/{{envID}}/as/token"
  method := "POST"

  payload := strings.NewReader("grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&subject_token_type=pingone_gateway_credential&subject_token=%7B%7BgatewayCredential%7D%7D")

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, payload)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  req.Header.Add("Authorization", "Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := io.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
POST /{{envID}}/as/token HTTP/1.1
Host: {{authPath}}
Content-Type: application/x-www-form-urlencoded
Authorization: Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&subject_token_type=pingone_gateway_credential&subject_token=%7B%7BgatewayCredential%7D%7D
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token_type=pingone_gateway_credential&subject_token={{gatewayCredential}}");
Request request = new Request.Builder()
  .url("{{authPath}}/{{envID}}/as/token")
  .method("POST", body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .addHeader("Authorization", "Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19")
  .build();
Response response = client.newCall(request).execute();
var settings = {
  "url": "{{authPath}}/{{envID}}/as/token",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": "Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19"
  },
  "data": {
    "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
    "subject_token_type": "pingone_gateway_credential",
    "subject_token": "{{gatewayCredential}}"
  }
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{{authPath}}/{{envID}}/as/token',
  'headers': {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19'
  },
  form: {
    'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange',
    'subject_token_type': 'pingone_gateway_credential',
    'subject_token': '{{gatewayCredential}}'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{{authPath}}/{{envID}}/as/token"

payload = 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&subject_token_type=pingone_gateway_credential&subject_token=%7B%7BgatewayCredential%7D%7D'
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Authorization': 'Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{authPath}}/{{envID}}/as/token');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Authorization' => 'Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19'
));
$request->addPostParameter(array(
  'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange',
  'subject_token_type' => 'pingone_gateway_credential',
  'subject_token' => '{{gatewayCredential}}'
));
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
require "uri"
require "net/http"

url = URI("{{authPath}}/{{envID}}/as/token")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/x-www-form-urlencoded"
request["Authorization"] = "Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19"
request.body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&subject_token_type=pingone_gateway_credential&subject_token=%7B%7BgatewayCredential%7D%7D"

response = http.request(request)
puts response.read_body
let parameters = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&subject_token_type=pingone_gateway_credential&subject_token=%7B%7BgatewayCredential%7D%7D"
let postData =  parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "{{authPath}}/{{envID}}/as/token")!,timeoutInterval: Double.infinity)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("Basic e3thZG1pbkFwcElEfX06e3thZG1pbkFwcFNlY3JldH19", forHTTPHeaderField: "Authorization")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in
  guard let data = data else {
    print(String(describing: error))
    return
  }
  print(String(data: data, encoding: .utf8)!)
}

task.resume()