{
  "info": {
    "_postman_id": "440132f5-b297-465e-bc0f-298ae8d74add",
    "name": "Signed Tokens",
    "description": "Requests a bearer token from a Duende IdentityServer using a private-key-signed JWT client assertion instead of a plain client secret.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Get Bearer Token (Signed JWT)",
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "//import jwt signing library",
              "var navigator = {};",
              "var window = {};",
              "eval(pm.globals.get(\"jsrsasign-js\"));",
              "",
              "//Obtain environment variables",
              "var idp = pm.environment.get('idpServer') || '';",
              "var iss = pm.environment.get('iss') || '';",
              "var sub = pm.environment.get('sub') || '';",
              "var aud = pm.environment.get('aud') || '';",
              "var alg = pm.environment.get('alg') || '';",
              "var privateKey = pm.environment.get('privateKey') || '';",
              "",
              "// Set headers for JWT",
              "var header = {",
              "\t'typ': 'JWT',",
              "\t'alg': `${alg}`,",
              "};",
              "",
              "// Prepare timestamp in seconds",
              "var currentTimestamp = Math.floor(Date.now() / 1000)",
              "",
              "// Set body data",
              "var data = {",
              "\t'iss': `${iss}`,\t",
              "    'sub': `${sub}`,",
              "\t'aud': `${aud}`,",
              "\t'exp': currentTimestamp + 300, // expiry time is 300 seconds from time of creation",
              "\t'jti': `${uuidv4()}`",
              "}",
              "",
              "data = addIAT(data);",
              "",
              "var keyObject = KEYUTIL.getKey(privateKey);",
              "var jwtSigned = KJUR.jws.JWS.sign(header.alg, JSON.stringify(header), JSON.stringify(data), keyObject);",
              "console.log('Signed and encoded JWT', jwtSigned);",
              "pm.environment.set('clientAssertion', jwtSigned);",
              "",
              "//create guid",
              "function uuidv4() {",
              "  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {",
              "    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);",
              "    return v.toString(16);",
              "  });",
              "}",
              "",
              "//create iat",
              "function addIAT(request) {",
              "    var iat = Math.floor(Date.now() / 1000) + 257;",
              "    data.iat = iat;",
              "    return data;",
              "}",
              ""
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const jsonResponse = pm.response.json();",
              "pm.environment.set(\"bearerToken\", jsonResponse.access_token);"
            ]
          }
        }
      ],
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/x-www-form-urlencoded"
          }
        ],
        "body": {
          "mode": "urlencoded",
          "urlencoded": [
            {
              "key": "client_assertion_type",
              "value": "{{clientAssertionType}}",
              "type": "text"
            },
            {
              "key": "client_id",
              "value": "{{clientId}}",
              "type": "text"
            },
            {
              "key": "grant_type",
              "value": "client_credentials",
              "type": "text"
            },
            {
              "key": "client_assertion",
              "value": "{{clientAssertion}}",
              "type": "text"
            },
            {
              "key": "scope",
              "value": "{{scope}}",
              "type": "text"
            }
          ]
        },
        "url": {
          "raw": "{{idpServer}}",
          "host": [
            "{{idpServer}}"
          ]
        }
      },
      "response": []
    }
  ]
}