• Share
    • Twitter
    • LinkedIn
    • Facebook
    • Email
  • Feedback
  • Edit
Show / Hide Table of Contents

How to get a system user ticket credential

Some tooltip text!
• 6 minutes to read
 • 6 minutes to read

To get the ticket, you must send a request containing a signed version of your system user token to the partner system user service endpoint.

The system user token is on of the claims in the id_token received the initial administrative authentication.

Pre-requisites

  • Client secret (obtained when application is registered)
  • ContextIdentifier (tenant identity)
  • System user token (application is authenticated)

There are several ways to obtain a system user ticket:

  1. Use our REST API, or
  2. Use our SOAP API, or
  3. Use one of our nuget packages

All three options require a signed version of the system user token. Please read the How to sign a system user token documentation to learn how to do that part of this flow.

Use the REST API

SuperOffice CRM Online exposes one REST endpoint for conducting the exchange:

https://{environment}.superoffice.com/Login/api/PartnerSystemUser/Authenticate

The following example is demonstrates the HTTP request.

@signed_Token=YOUR_SIGNED_TOKEN
@client_Secret=YOUR_CLIENT_SECRET
@context_Identifier=YOUR_CUSTOMER_ID

POST https://{environment}.superoffice.com/Login/api/PartnerSystemUser/Authenticate
Content-Type: application/json
Accept: application/json

{
    "SignedSystemToken": "{{signed_Token}}",
    "ApplicationToken": "{{client_secret}}",
    "ContextIdentifier": "{{context_Identifier}}",
    "ReturnTokenType": "JWT"
}

Use the SOAP API (NodeJS)

SuperOffice CRM Online exposes one WCF SOAP endpoint for conducting the exchange:

https://onlineenv.superoffice.com/login/services/PartnerSystemUserService.svc

Download the PartnerSystemUserService WSDL

The SOAP envelope should contain 2 header elements and the AuthenticationRequest element in the SOAP body.

<?xml version="1.0" encoding="UTF-8"?>
  <SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/"
                     xmlns:ns1="http://www.superoffice.com/superid/partnersystemuser/0.1"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:tns="http://www.superoffice.com/superid/partnersystemuser/0.1"
                     xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header>
      <tns:ApplicationToken>${appToken}</tns:ApplicationToken>
      <tns:ContextIdentifier>${contextId}</tns:ContextIdentifier>
    </SOAP-ENV:Header>
    <ns0:Body>
      <ns1:AuthenticationRequest>
        <ns1:SignedSystemToken>${signedToken}</ns1:SignedSystemToken>
        <ns1:ReturnTokenType>Jwt</ns1:ReturnTokenType>
      </ns1:AuthenticationRequest>
    </ns0:Body>
  </SOAP-ENV:Envelope>

Use a nuget package

We provide the following .NET nuget packages to help perform the task.

SuperOffice.WebApi (preferred)

  • SuperOffice.WebApi (nuget)
  • Sample Code on GitHub

SuperOffice.Crm.Online.Core (legacy)

  • SuperOffice.Crm.Online.Core
  • Sample Code on GitHub

How to get system user ticket

The following example code has an extensive amount of logging to the console. This lets you see the output from each step. The final output is the system user ticket. It performs the following steps:

  1. Read the partner's private PEM file.
  2. Sign system user token.
  3. Send request to SuperOffice.
  4. Gets the response to obtain the JWT.
  5. Validate JWT token.
  6. Extract the system user ticket.

  • REST
  • SOAP
NPM package.json file for NodeJS REST example.

package.json file

{
  "name": "devnet-nodejs-systemuser-rest",
  "version": "1.0.0",
  "description": "Signs system user token and requests system user ticket",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },
  "author": "AnthonyYates",
  "license": "MIT",
  "dependencies": {
    "axios": "^0.26.1",
    "crypto": "^1.0.1",
    "jsonwebtoken": ">=9.0.0",
    "moment": "^2.22.2"
  }
}

index.js code

const crypto = require('crypto');
const moment = require('moment');
const fs = require('fs');
const axios = require('axios');
const jwt = require('jsonwebtoken');

// specify the environment
// sod      => development
// qastage  => stage
// online   => production
const env = 'sod';

// Partner Application Token (AKA Client Secret)
const appToken = 'YOUR_APPLICATION_TOKEN_GOES_HERE';

// Your Online Sandbox Customer Identifier
const contextId = 'Cust12345';

// SystemUserToken provided as a claim in the callback (Redirect URL)
// when a tenant administrator successfully signs into SuperID.
const systemToken = 'YOUR_SYSTEM_USER_TOKEN_GOES_HERE';

// Partners private key
const privKeyFile = 'privatekey.pem';

// SuperOffice public key (SOD) 
// Open SuperOfficeFederatedLogin.crt in notepad,
// save contents as SuperOfficeFederatedLogin.pem
const publKeyFile = 'SuperOfficeFederatedLogin.pem';

const getSystemUserTicket = async () => {
  try {
    const privateKeyFile = fs.readFileSync(privKeyFile,'utf8');
    const publicKeyFile  = fs.readFileSync(publKeyFile, 'utf8');
  
    // prepare the datetime stamp
    const utcTimestamp = moment.utc().format('YYYYMMDDHHmm');
    const data = `${systemToken}.${utcTimestamp}`;
    
    log('Token.Time: ' + data);
  
    // sign the System User token
    let sign = crypto.createSign('SHA256');
    sign.update(data);
    sign.end();
    sign = sign.sign(privateKeyFile, 'base64');
    const signedToken = `${data}.${sign}`;
    
    log('Signed Token: ' + signedToken);
  
    // send the request
  
    var postData = {
        'SignedSystemToken': `${signedToken}`,
        'ApplicationToken': `${appToken}`,
        'ContextIdentifier': `${contextId}`,
        'ReturnTokenType': 'JWT'
    };
    
    let axiosConfig = {
      headers: {
          'Content-Type': 'application/json;charset=UTF-8',
          "Accept": "application/json;charset=UTF-8"
      }
    };
  
    const jwtRes = await axios.post(`https://${env}.superoffice.com/Login/api/PartnerSystemUser/Authenticate`, postData, axiosConfig);
  
    if(jwtRes.data.IsSuccessful)
    {
      var token = jwtRes.data.Token;
  
      var verifyOptions = {
        ignoreExpiration: true,
        algorithm: ["RS256"]
      };
    
      // validate the JWT and extract the claims
      var decoded = jwt.verify(token, publicKeyFile, verifyOptions);
      
      // write out the ticket to the console, DONE!
      const ticket = decoded["http://schemes.superoffice.net/identity/ticket"];
      return ticket;
    } else {
      log('Getting the System User ticket was unsuccessful: ' + jwtRes.data.ErrorMessage);
    } 
  } catch (error) {
    log("Error: " + error);
  }  
}

function log(message) {
  console.log('')
  console.log(message)
}

// Finally, execute the function to get the system user ticket!

(async () => {
  try {
    const result = await getSystemUserTicket();
    log("System User Ticket: " + result);
  } catch (error) {
    log(error);
  }
})();
NPM package.soap.json file for NodeJS SOAP example.

package.soap.json file

Warning

It looks like the sample you are looking for does not exist.

index.soap.js code

{
  "name": "devnet-nodejs-systemuser-soap",
  "version": "0.0.1",
  "description": "Exchange system user token for system user ticket.",
  "main": "index.js",
  "scripts": {
    "start": "node index.soap.js"
  },
  "author": "AnthonyYates",
  "license": "MIT",
  "dependencies": {
    "crypto": "^1.0.1",
    "jsonwebtoken": ">=9.0.0",
    "moment": "^2.22.2",
    "request": "^2.88.0",
    "xml2js": "^0.4.19"
  }
}
In This Article
© SuperOffice. All rights reserved.
SuperOffice |  Community |  Release Notes |  Privacy |  Site feedback |  Search Docs |  About Docs |  Contribute |  Back to top