Skip to main content
Skip table of contents

Integrating Custom Embeds

Embeds are a great way of seamlessly integrating AppsAnywhere with your current hub setup, however that may look. We have built in LMS support for both Blackboard and Canvas, but we still want to provide this feature to all other portals. By following this guide we hope that you understand what is involved in curating your portal to include AppsAnywhere.


  1. You have added an Embed with type Custom Embed (requires AppsAnywhere 3.2)

  2. The Shared App Lists feature is enabled

Once these are completed, you can proceed to the next step.

Configuring an example

We have provided an example index.php alongside this guide in hopes that this can be duplicated within your portal, once this example web page is running it should look something like this:

At first this button will not work as we need to configure the different variables to work for your system. There are a handful of these we need to look at and are noted below.





The full domain name or load balanced address for your AppsAnywhere instance.


The unique course identifier.



The course display name.



The username matching the LDAP record or SAML attribute of the AppsAnywhere user - this is matched via the Embed authorization method.



The name of the field AppsAnywhere will retrieve the username from. This value defaults to lis_person_sourcedid.



The role of the user, whether they can edit the list of applications or not. Administrators and Instructors can select the associated list, Students can only launch applications.





The Consumer Key taken from the AppsAnywhere Embed.



The Consumer Secret taken from the AppsAnywhere Embed.


Once we have read and understood the different variables, we need to plug them into our example code. For this example, you should focus on providing the host, username, consumerKey and consumerSecret.

The consumerSecret should be treated as confidential, the usage here is only for the example and this should be handled more securely in your implementation.

When this is done, refresh your web page and confirm these new details are now shown - then we can hit submit.


// Your variables
$host = ''; // Your AppsAnywhere url

$courseId = '1'; // Identifier for this course
$courseCode = 'ENG-101'; // Display name for this course
$username = 'adam.willcock'; // The username, matching the SSO or LDAP user
$usernameField = 'lis_person_sourcedid'; // This field name can be configured in the AppsAnywhere Embed, defaults to 'lis_person_sourcedid'

// Comma separated list of roles, replace as required e.g. 'urn:lti:role:ims/lis/Administrator,urn:lti:role:ims/lis/Instructor'
//$roles = 'urn:lti:instrole:ims/lis/Student';// If neither admin nor instructor then the list is read-only
//$roles = 'urn:lti:role:ims/lis/Instructor'; // 'urn:lti:role:ims/lis/Instructor' or 'urn:lti:role:ims/lis/Administrator' can edit and associate app lists
$roles = 'urn:lti:role:ims/lis/Administrator'; // Provides the same level of admin as Instructor, however this is meant for global admins

$consumerKey = ''; // The consumer key copied from the AppsAnywhere Embed
$consumerSecret = ''; // The consumer secret copied from the AppsAnywhere Embed

If all is well, you should then see the embed load as shown here:

Once the embed is displaying correctly, you can now start on our App List Administration For Custom Embeds documentation.


If you are having issues in getting the embed to load after adding your configuration, we should confirm a few things:

  1. It’s usually a good idea to ensure you are logged out of AppsAnywhere for each attempt at using the embed, you can be sure of this by visiting https://{host}/logout

  2. Be sure to refresh the example web page and try again as it creates a unique signature each time

  3. Can you visit https://{host} and see the login screen?

  4. Can you login using your username?

  5. Is the Embed you created of type Custom Embed?

  6. Do the consumerKey and consumerSecret match the values taken from the Embed?

  7. Does the usernameField match the value in the Embed? (blank being lis_person_sourcedid)

  8. Is the Embed authorization method the same being used to login?

How it works

The premise of the example is based around the use of OAuth signature creation, this is the most important part to get right as otherwise access to the embed will be denied. All of what is done here is explained within the OAuth documentation and you may want to refer to this when customising your own implementation.

The form parameters listed here are what need to be sent to AppsAnywhere, we then use this list to verify the request via OAuth and log the user in with the correct permissions for the course. You should not have to edit any of this for the example file to run. Though of course you are free to implement this however you prefer.

$params = [
    'custom_appsanywhere_custom_embed_course_code' => $courseCode,
    'custom_appsanywhere_custom_embed_course_id' => $courseId,
    'roles' => $roles,
    'oauth_consumer_key' => $consumerKey,
    $usernameField => $username,
    'oauth_timestamp' => time(), // The current timestamp for OAuth
    'oauth_nonce' => bin2hex(random_bytes(32)), // An OAuth nonce (limited to 96 characters)
    'tool_consumer_info_product_family_code' => 'Test-System', // Free to be whatever you like
ksort($params); // Params must be ordered by key

The key parts to note are the ordering of these params by key, and also the use of & throughout and when this is/isn’t being url encoded.

$method = 'POST&';
$baseUrl = rawurlencode("https://{$host}/lti/application/embed") . '&';

// Parse params
$paramString = '';
foreach ($params as $key => $value) {
    $paramString .= rawurlencode($key) . '=' . rawurlencode($value) . '&';
$paramString = rawurlencode(rtrim($paramString, '&'));

// Create base string for oauth signature
$baseString = $method . $baseUrl . $paramString;
$signature = base64_encode(hash_hmac('sha1', $baseString, $keySecret . '&', true));

It is especially important to note the $keySecret here appended with an &, not doing this will result in wildly different signatures to AppsAnywhere.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.