PingOne Platform APIs

Token Revocation

POST {{authPath}}/{{envID}}/as/revoke

The POST /{{envID}}/as/revoke endpoint revokes the token specified in the request body. The revocation endpoint applies to access_token and refresh_token tokens, and the tokens to be revoked must be for a custom resource. Tokens issued for the PingOne API resource may not be revoked because the PingOne APIs do not use the introspection endpoint. Also, custom resource tokens that do not have a sid (session) claim, such as tokens issued for the client_credentials grant type, cannot be revoked.

For more information about the token revocation request, refer to section 2.1 of OAuth 2.0 Token Revocation. For more information about custom resources, custom scopes, and how the PingOne OAuth 2 authorization service manages requests for custom scopes, refer to Custom scopes in PingOne for Developers - Foundations.

The POST /{{envID}}/as/revoke endpoint uses the same authentication method as the POST /{{envID}}/as/token endpoint, and uses the value from the application’s tokenEndpointAuthMethod to determine the configuration. If the tokenEndpointAuthMethod is set to CLIENT_SECRET_BASIC, the Authorization: Basic <headerValue> represents a Base64-encoded representation of "username:password", in which the username is the client_id and the password is the client_secret.

If the application’s tokenEndpointAuthMethod value is CLIENT_SECRET_POST, the request does not need an Authorization header, and the client_id and client_secret property values are submitted in the request body.

If the application’s tokenEndpointAuthMethod value is NONE, the request requires the client_id property value in the request body and does not require an Authorization header.

If the application’s tokenEndpointAuthMethod value is CLIENT_SECRET_JWT, the token endpoint uses a JWT signed by the application’s client secret to authenticate the request. For information about creating the JWT and the claims in the JWT, refer to Create a client secret JWT.

If the application’s tokenEndpointAuthMethod value is PRIVATE_KEY_JWT, the token endpoint uses a JWT signed by an external private key file to authenticate the request. For information about creating the JWT and the claims in the JWT, refer to Create a private key JWT.

This endpoint does not support individual one-by-one access token revocation. This operation revokes all access tokens for the session and application combination. A token must have an associated session (sid) claim to be revoked. If you revoke a refresh token, it also revokes all associated access tokens to that specific session and application combination. Revocation applies to tokens issued up to the current time of the revocation call and has no relation to the iat (issued at) claim of the token being revoked, nor does it affect tokens issued after the time of the revoke call even if for the same session and application combination.

If the authentication method is accepted, and the token contains the necessary custom resource aud and sid claims, the response returns a 200 code with an empty body.

If the token is invalid or if the token does not include the sid claim, an unsupported_token_type error is returned as directed in OAuth 2.0 Token Revocation RFC7009 (section 2.2.1). If the aud claim identifies a platform token, an unsupported_token_type error response is returned.

For more information about PingOne SSO sessions and token revocation, refer to OIDC session management in the PingOne for Developers Guide.

Prerequisites

Request Model
Property Type Required?

token

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

token

{{oauthToken}}

Example Request

  • cURL

  • C#

  • Go

  • HTTP

  • Java

  • jQuery

  • NodeJS

  • Python

  • PHP

  • Ruby

  • Swift

curl --location --globoff '{{authPath}}/{{envID}}/as/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=' \
--data-urlencode 'token={{oauthToken}}'
var options = new RestClientOptions("{{authPath}}/{{envID}}/as/revoke")
{
  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 e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=");
request.AddParameter("token", "{{oauthToken}}");
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
package main

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

func main() {

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

  payload := strings.NewReader("token=%7B%7BoauthToken%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 e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=")

  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/revoke HTTP/1.1
Host: {{authPath}}
Content-Type: application/x-www-form-urlencoded
Authorization: Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=

token=%7B%7BoauthToken%7D%7D
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "token={{oauthToken}}");
Request request = new Request.Builder()
  .url("{{authPath}}/{{envID}}/as/revoke")
  .method("POST", body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .addHeader("Authorization", "Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=")
  .build();
Response response = client.newCall(request).execute();
var settings = {
  "url": "{{authPath}}/{{envID}}/as/revoke",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": "Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0="
  },
  "data": {
    "token": "{{oauthToken}}"
  }
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{{authPath}}/{{envID}}/as/revoke',
  'headers': {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0='
  },
  form: {
    'token': '{{oauthToken}}'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

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

payload = 'token=%7B%7BoauthToken%7D%7D'
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Authorization': 'Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0='
}

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/revoke');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Authorization' => 'Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0='
));
$request->addPostParameter(array(
  'token' => '{{oauthToken}}'
));
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/revoke")

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 e3thcHBJRH19Ont7YXBwU2VjcmV0fX0="
request.body = "token=%7B%7BoauthToken%7D%7D"

response = http.request(request)
puts response.read_body
let parameters = "token=%7B%7BoauthToken%7D%7D"
let postData =  parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "{{authPath}}/{{envID}}/as/revoke")!,timeoutInterval: Double.infinity)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("Basic e3thcHBJRH19Ont7YXBwU2VjcmV0fX0=", 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()