跳至主要內容
Adaptive Planning
Make Adaptive Planning API Requests with Workday Credentials

Make Adaptive Planning API Requests with Workday Credentials

Some links in this article go to the Workday Community. If you don't have a Community account, request one.
Workday-synchronized users who log in to Workday and use the
Adaptive Planning
Worklet can run
Adaptive Planning
public APIs. Users must create an ISU specifically for making these API requests. These users must provide a token in the
credentials
element of
Adaptive Planning
API requests instead of a username and password. You can cache this token and use it until it expires. After it expires, you must get a new token.

Prerequisites

Workday Domain and Security Groups
  • Verify the ISU users who need API access are part of the
    Set Up: Adaptive Planning API Access
    security domain.
Workday Setup Tasks
  • Verify that
    Single Sign-On
    tasks are enabled within the
    User Sign-on
    tab in the
    Adaptive Planning
    tab.
  • Verify the
    Public API setup
    task is enabled within the
    Public API
    tab in the
    Adaptive Planning
    tab.
  • Verify an integration system user (ISU) setup task created an ISU specifically for making Workday Adaptive Planning API requests and mapped it to an
    Adaptive Planning
    user account.
Adaptive Planning
User Admin
  • Verify you see the ISU beginning with
    PublicAPIISU_
    in the users list within Administration > Users.
  • Verify this user has the level access needed for the APIs they want to run. New ISUs don't receive level access by default.

Steps

  1. Get a Certificate and Extract your Public Key.
  2. Register an API Client in Workday with that certificate.
  3. Generate a JWT Token, Retrieve Workday access_token, and Retrieve AdaptiveAPIAccessToken.
  4. Use the AdaptiveAPIAccessToken in an
    Adaptive Planning
    API Request.

Get a Certificate and Extract your Public Key

You can create a certificate yourself or purchase a certificate from a well-known certificate authority. For the details on the parameters needed for your X.509 Certificate in Workday, see Concept: X.509 Certificates in Workday.
  1. Extract the public key from your certificate for uploading to Workday.
  2. Retain your private key for use in your calling application.
  3. Paste the certificate into Workday when registering your JWT bearer token. Reference your private key in your script.

Register a Workday API Client

  1. Register an API Client with
    Client Grant Type: Jwt Bearer Grant
    in Workday. See Register an API Client for more information.
  2. Copy the public key derived for your certificate into the
    x.509 Certificate
    in the Register API Client page in Workday.
  3. For
    Scope (Functional Area)
    select
    Adaptive Planning
    .
  4. When you finish registering the API client, copy the resulting fields at the bottom of the page to a text file to use later.
    • Workday REST API Endpoint
    • Token Endpoint
    • Authorization Endpoint

Generate JWT Token, Retrieve Workday access_token, and Retrieve AdaptiveAPIAccessToken

  1. Use your private key and generate the JWT token by running pseudo code listed below.
  2. To retrieve a Workday access token, make a
    POST
    request to the Token Endpoint, passing
    grant_type
    and
    assertion
    . Use the Token Endpoint copied after registering your API client in Workday. Example Token Endpoint:
    https://{host or gateway}/ccx/oauth2/{tenant}/token
    Example
    CURL
    request to the Token Endpoint
    curl --request POST 'https://{host or gateway}/ccx/oauth2/{tenant}/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \ --data-urlencode 'assertion={{the jwt assertion from your certificate}}'
  3. Retrieve the AdaptiveAPIAccessToken by calling the Workday endpoint using the Workday access token. Use the prior
    access_token
    value as the Bearer token in the
    Auth
    header for this
    GET.
    Example Access Token:
    https://{host or gateway}/ccx/api/planning/v1/{tenant}/adaptiveAPIAccessToken
    Example
    CURL
    request for the AdaptiveAPIAccessToken:
    curl --request GET 'https://{host or gateway}/ccx/api/planning/v1/{tenant}/adaptiveAPIAccessToken' \ --header 'Authorization: Bearer {{the prior access_token value}}' \ --data-raw ''
  4. Call the
    Adaptive Planning
    API using the AdaptiveAPIAccessToken in the credentials element of the XML in an HTTP
    POST
    . Example:
    curl -H "Content-Type: text/xml" -d '<?xml version='1.0' encoding='UTF-8'?><call method="exportLevels" callerName="a string that identifies your client application"><credentials token="ID eyJhbDci0iJSUzUxMiIsUmtpZCI6IdvcmtkYXlfa2V5In0.eyJpc3KiOiJXb3JrZGFZIiwiYXV0aF90aW1lIjoxNTczMTY3NjU2LBjzeXnfynnJd.bztQzBmHeTj1amnHA-r96TdrJK0MXMghUFF1KyjxqIq6ruHU63dJp3JAJn3Eche7SEcoZBVGX4wJgna106pmCqgrrVWMf13Hg_sb_szabal2XN1KEEk1qh8z1IDlbt6qJIL_xyW3J2nNSs5ima3vJUYU5sRQXwXst0GuFWXpy464GyB4oKcscrg28X3dnPO_ytdohMKHsWkqyHQKXFQwoQezFaGy10sp4RRUj0lpOZX8C9oBHDYA58IXxGkqKLJVNPvDND6rGY5fTHQ-yxpe1nz-WqB0boiq9a-dv8b3EBzbelxj2fCPdMbng6kzygDcA2at_7BNQiyzfIovS5AG"/><include versionID="3" inaccessibleValues="false"/><sheet id="3" /></call>' -X POST https://api.adaptiveplanning.com/api/v23

Sample Java Application for Generating a JWT Token

This sample Java application generates a JWT token.
//********************************************************************** // // File: TestPublicAPISample.java // // Copyright 2004-2019 Workday Adaptive Planning. // All Rights Reserved. // // This work contains trade secrets and confidential material of // Workday Adaptive Planning and its use or disclosure in whole or in part // without the express written permission of Workday Adaptive Planning is prohibited. // //********************************************************************** import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Signature; import java.text.MessageFormat; //import java.util.Base64; import org.apache.commons.codec.binary.Base64; public class AccessAdaptiveAPI { public static void main(String args[]) { String jwtKeyStoreFileString = "/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/security/JWTkeystore.jks"; String clientIDString = "BlywNDM1NmMtZTk2Mi00NTZiTWEyZjktZWM1NGJiOGQ3Yjca"; String userIdString = "PublicAPIISU_Test"; System.out.println(GetAccessToken(clientIDString,userIdString,jwtKeyStoreFileString)); } public void callAPI() { } public String getAdaptiveAPIToken() { return ""; } public String getJWTToken(String privateKey, String username) { return ""; } public void callWorkdayAPI() { } public static String GetAccessToken(String clientId, String userId, String jwtKeyStore) { String header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"; String claimTemplate = "'{'\"iss\": \"{0}\", \"sub\": \"{1}\", \"aud\": \"{2}\", \"exp\": \"{3}\"'}'"; try { StringBuffer token = new StringBuffer(); //Encode the JWT Header and add it to our string to sign token.append(Base64.encodeBase64URLSafeString(header.getBytes("UTF-8"))); //Separate with a period token.append("."); //Create the JWT Claims Object String[] claimArray = new String[4]; //iss claimArray[0] = clientId; //sub claimArray[1] = userId; //aud claimArray[2] = "wd"; //exp claimArray[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300); MessageFormat claims; claims = new MessageFormat(claimTemplate); String payload = claims.format(claimArray); //Add the encoded claims object token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8"))); //token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8"))); //Load the private key from a keystore KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream(jwtKeyStore), "Workday123!".toCharArray()); PrivateKey privateKey = (PrivateKey) keystore.getKey("Workday", "Workday123!".toCharArray()); //Sign the JWT Header + "." + JWT Claims Object Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(privateKey); signature.update(token.toString().getBytes("UTF-8")); String signedPayload = Base64.encodeBase64URLSafeString(signature.sign()); //Separate with a period token.append("."); //Add the encoded signature token.append(signedPayload); return token.toString(); //System.out.println(token.toString()); } catch (Exception e) { e.printStackTrace(); } return ""; } }

Sample C# Application for Generating a JWT Token

This sample C# application generates a JWT token that replaces the username and password in the credentials element of an
Adaptive Planning
API request.
This sample code requires a NuGet page. Required NuGet package:
System.IdentityModel.Tokens.Jwt
var clientId = "BlywNDM1NmMtZTk2Mi00NTZiTWEyZjktZWM1NGJiOGQ3Yjca";//Client ID from workday API Client var isu = "PublicAPIISU_Test"; //the ISU var timeout = (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000 + 300).ToString(CultureInfo.InvariantCulture); var environment = "wd"; var pfxFilePath = @"C:\temp\JWTkeystore2.pfx"; var pfxPassword = "Workday123!"; var payload = new JwtPayload { {"iss", clientId}, {"sub", isu}, {"aud", environment}, {"exp", timeout }, }; var signingCredentials = new X509SigningCredentials(new X509Certificate2(pfxFilePath, pfxPassword), SecurityAlgorithms.RsaSha256); // the matching PKCS #12 file with private key var jwtHeader = new JwtHeader(signingCredentials); var secToken = new JwtSecurityToken(jwtHeader, payload); var handler = new JwtSecurityTokenHandler(); var tokenToWorkday = handler.WriteToken(secToken); Console.WriteLine(tokenToWorkday);

Use the AdaptiveAPIAccessToken in an
Adaptive Planning
API Request

Once you set up Workday for
Adaptive Planning
public API access, the credentials element of
Adaptive Planning
API requests use the AdaptiveAPIAccessToken instead of a username and password. Basic authentication with username and password won't work. See Adaptive Planning REST API and API Methods for more.

Example AdaptiveAPIAccessToken in an
Adaptive Planning
API Request

<?xml version='1.0' encoding='UTF-8'?> <call method="exportLevels" callerName="a string that identifies your client application"> <credentials token="ID eyJhbDci0iJSUzUxMiIsUmtpZCI6IdvcmtkYXlfa2V5In0.eyJpc3KiOiJXb3JrZGFZIiwiYXV0aF90aW1lIjoxNTczMTY3NjU2LBjzeXnfynnJd.bztQzBmHeTj1amnHA-r96TdrJK0MXMghUFF1KyjxqIq6ruHU63dJp3JAJn3Eche7SEcoZBVGX4wJgna106pmCqgrrVWMf13Hg_sb_szabal2XN1KEEk1qh8z1IDlbt6qJIL_xyW3J2nNSs5ima3vJUYU5sRQXwXst0GuFWXpy464GyB4oKcscrg28X3dnPO_ytdohMKHsWkqyHQKXFQwoQezFaGy10sp4RRUj0lpOZX8C9oBHDYA58IXxGkqKLJVNPvDND6rGY5fTHQ-yxpe1nz-WqB0boiq9a-dv8b3EBzbelxj2fCPdMbng6kzygDcA2at_7BNQiyzfIovS5AG"/> <include versionID="3" inaccessibleValues="false"/> <sheet id="3" /> </call>