Technical Articles
F5 SMEs share good practice.
cancel
Showing results for 
Search instead for 
Did you mean: 
Lucas_Thompson
F5 Employee
F5 Employee

Introduction

This guide will walk through how the logon, webtop, and other UI pages are created by APM, how it works, and some examples.The new APM modern template has an updated look in both mobile and desktop browsers. It uses the popular Preact framework to provide a consistent and familiar end user experience.

0151T000003lmAhQAI.png

 

How to activate the new customization system

New policies created in 15.1 and later default to the new Modern template. Existing policies made before 15.1 continue to use the Standard template.

When creating a new access policy:

0151T000003lmAmQAI.png

 

You can see the customization types applied to all access policies in the Per-Session access policy menu:

Customization Sections

Basic, General, and Advanced Customization

APM has different ways to customize, depending on the desired complexity. Some administrators simply want to change colors, while others would prefer to completely rewrite the APM user-facing HTML and CSS so they have similar branding to other corporate web properties. As is typical with CSS, style customizations can be applied simultaneously with later style changes overriding earlier ones.

0151T000003lmAJQAY.png

 

Basic Customization

Simple customization settings such as images, titles, captions, and colors are applied to resources and policies using Basic Customization. The tables and screenshot below detail the settings.

0151T000003lmAnQAI.png

0151T000003lmArQAI.png

Elements in Basic Customization

Header/Footer/Title

  • Header Image for Desktop (Max height: 60px) 
  • Header Image for Mobile (Max height: 30px) 

Layout Settings

  • Maximum viewport width for applying small (mobile) screen styles (px) 
  • Browser width for mobile clients
  • Minimum viewport width for applying large (desktop) screen styles (px) 
  • Browser width for desktop clients

Colors (see image for sections)

  • Active Links and Buttons Color 
  • Footer Background Color 
  • Form Background Color
  • Header Color
  • Page Background Color
  • Solid Button Text Color
  • Text Color
  • Top Strip Color

General Customization

General Customization offers a more advanced tree view of the Basic Customization settings as well as text options for user-facing messages. Like Basic customization, the settings are applied individually to each access policy and policy item via the item’s XML file specified in the cache-path parameter of the associated customization group configuration object.

To use General Customization

  1. Create the policies and/or resources you would like to customize.
  2. Find them in the tree view.
  3. Make the changes.
  4. Perform the standard 3-step save process: Save Draft, Save, then Apply the access policy.

0151T000003lmAsQAI.png

 

You use General Customization to apply changes to the informational text strings and error messages that are displayed to users. Browse the configuration tree to see the available customization areas.

The settings are divided into Branding and Text. Text are the localized messages that are displayed to the end users, including associated HTML. User-facing status and text messages can be selected in the Text tab. Branding options are about page styling, colors, fonts, and the like. These are selected in the Branding tab.

Special General Options 

APM customization has a few non-branding and non-text special options in the configuration tree.

Disable all external scripts and styles

The new Modern customization includes a new resource loader feature. This feature loads all added CSS and JS resources dynamically, including 3rd party external code. You use this option like a “Revert” to restore the default branding in case there is some unknown trouble. If enabled, it disables loading of all external CSS and JS, including the APM-hosted user-XXXX.js and user-XXXX.css files.

0151T000003lmAwQAI.png

 

External Javascript / CSS

You can now easily add external javascript references, for libraries such as JQuery that you would like your users to load from an external CDN. Historically this would present a security problem because the CDN content may be vulnerable to malicious injection. APM uses the W3C subresource integrity feature(https://www.w3.org/TR/SRI/) mechanism to ensure that the external files are not tampered.

You can also specify external scripts manually in user-XXXX.js, but using the inbuilt APM script-loader mechanism allows us to trap loading errors and disable all external scripts globally, in case of any problems (see the previous section).

To use this feature:

  1. Find the checksum* and URL of your resource. jQuery makes this very simple: It’s directly on their CDN page. Alternatively, you can compute them using srihash.org.0151T000003lmAKQAY.png
  2. Place the values into External Scripts / Styles.0151T000003lmALQAY.png
  3. Save, Apply the access policy, and visit the access policy virtual.

*Note*: APM’s end-user pages are built using Preact with built-in libraries, so don't load another copy of Preact using this mechanism. See the Advanced Examples section below for usage ideas.

If the checksum is incorrect the stock APM javascript will function correctly, but the external resource will not be loaded and the browser will produce a “Failed to find a valid digest in the integrity attribute for resource ‘xxxxxx’” error in the console similar to this screenshot:

0151T000003lmAxQAI.png

* Supported checksum mechanisms are SHA-256, SHA-384, or SHA-512.

Advanced Customization

Use Advanced Customization to edit or place code directly into the files that are referenced from the primary APM user-facing HTML. Common settings are available which load on all pages, along with separate CSS and JS for each policy item that is present in the policy. Generally, the CSS/JS for each policy item load after the common settings so later settings will override earlier ones.

You must first add policy items to customize before customizing them. This is a customization tree view before and after adding Logon Page to access policy:

Before
0151T000003lmAMQAY.png
After
0151T000003lmB1QAI.png

Operation of Advanced Customization

With Advanced Customization, you can do essentially any styling you want using standard CSS.
Advanced Customization has some common settings, agent settings, and some special settings. After making any change, Save Draft, then Save., then Apply the access policy.

0151T000003lmB2QAI.png

Common settings

These two files (user-common.css and user-common.js) are loaded on all* APM user-facing pages, including policy evaluation (logon, message, etc), webtop, and logout.

Use these if you want to change a page style in all areas. For example, perhaps we always want to hide the header and footer and add a background image. To do that, we can simply add some CSS to user-common.css to set a few properties targeting the apmui-header, apmui-main, and apmui-footer CSS selectors.

Example: logon page customization

0151T000003lmAtQAI.png

Hide header and footer, and add a picture:

0151T000003lmAuQAI.png

*Note*: You should usually make logon-specific changes on the logon page rather than “common”, since the webtop places some GUI links in apmui-header. Hiding the header removes access to these links!

You can use user-common.js to load a tracker such as Google Analytics.

Example: Google Analytics

0EM1T000002Kz1m.jpg

Customization Types

There are two broad categories for the customization of APM objects:

Resources are Assigned during per-session access policy execution. They include customizable icons, captions, and descriptions that are visible on the APM full webtop (sometimes called a portal).

  • OAuth Client App
  • OAuth Scope
  • App Tunnel
  • Network Access
  • Remote Desktop
  • SAML
  • Web App (Portal Access)
  • Webtop Link
  • Webtop Section

Non-Resources each have different configuration properties

  • General
  • Framework Installation
  • EPS
  • Logout (Ending Denied)
  • Error message
  • Decision Box
  • Confirm/Continue
  • Ending Denied
  • Message Box
  • Oauth Authz
  • Webtop

Screenshots

*Example*: Simple resource customization of a webtop link resource

0151T000003lmAoQAI.png

End-User view from APM webtop:

0151T000003lmB3QAI.png

 

Troubleshooting Tips: Configuration Structure

Resource customization settings, text strings, and image files are stored as interdependent configuration and file objects. When troubleshooting, check the following configuration areas.

This diagram represents the dependencies:

0151T000003lmAvQAI.png

 

This table represents the item details, and troubleshooting tips:

0151T000003lmBLQAY.pngNOTE: To create resource customization using scripting or automation, they must be created all at once using a TMSH transaction rather than individually because of the interdependency between resources, profiles, policies, policy items, agents, and customization groups. To get started, use the GUI to create a policy you like, then review the configuration objects defined in tmsh list apm. The objects inter-referred-to must be copied into a transaction. equivalent create apm xxxx commands inside of a transaction. For detail on transactions with APM policies, see

 tmsh help apm policy access-policy
 tmsh help cli transaction

HTML Rendering Details

Access profiles, Per Request Policies and other objects (customized independently from an access profile) share similar syntax and structure. Each object has customization settings. Access Profiles have multiple groups of customization settings. Every time you change customization, it generates a set of files that are combined to form the user-displayed page. 

Settings (color, font, text, and so on) for the header and footer can be defined in access profile customization. Settings for the location and alignment of the content area can also be defined in access profile customization. Settings for resources displayed in the APM Webtop can be defined in the resource's configuration area (see payroll example above).

APM Sandbox / Image Hosting

To place images or other files in APM for convenient access by end users, use the Hosted Content feature.

  1. On a BIG-IP system, on the Main tab, click Access > Webtops > Hosted Content > Manage Files.
  2. Upload an image file.
  3. Click Upload >> Manage Access, and make sure the checkbox for your access policy attached to the virtual server is selected.
  4. Access the file at the location indicated in the Publicly Accessible URI column.

General Examples

Execute external javascript code after Logon Page browser rendering is complete.

This example can be placed into user-logon.js to use the D3 library to display a small pop-up message. Additional code can be inserted for custom functions.

define(["require", "exports", "tslib", "module", "apmui/page/logon/View"], function (require, exports, tslib_1, module, View_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    requirejs.config({
        map: {
            'apmui/master/View': {
                'apmui/page/logon/View': module.id,
            },
        },
    });
    /* Replacement View component */
    var CustomLogonView = /** @class */ (function (_super) {
        tslib_1.__extends(CustomLogonView, _super);
        function CustomLogonView() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        CustomLogonView.prototype.componentDidMount = function () {
            _super.prototype.componentDidMount.call(this);
            requirejs(['https://d3js.org/d3.v6.min.js'], function (d3) {
                
                // Place your code inside this function
                
                d3.select("form").append("span")
                .text("Hello from D3 library");                
            });
        };
        return CustomLogonView;
    }(View_1.default));
    exports.default = CustomLogonView;
});

Execute local javascript code inside Logon Page.

This example can be placed into user-logon.js to perform custom actions.

define(["require", "exports", "tslib", "module", "apmui/page/logon/View"], function (require, exports, tslib_1, module, View_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    requirejs.config({
        map: {
            'apmui/master/View': {
                'apmui/page/logon/View': module.id,
            },
        },
    });
    /* Replacement View component */
    var CustomLogonView = /** @class */ (function (_super) {
        tslib_1.__extends(CustomLogonView, _super);
        function CustomLogonView() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        CustomLogonView.prototype.componentDidMount = function () {
            _super.prototype.componentDidMount.call(this);

            alert('PLACE CUSTOM CODE HERE');

        };
        return CustomLogonView;
    }(View_1.default));
    exports.default = CustomLogonView;
});

Advanced Examples

These use TypeScript and preact You should be familiar with these technologies and their usage. To use these examples, you need a standard TypeScript/NodeJS+NPM build environment. This can be most easily achieved by using Linux, Microsoft Windows Subsystem for Linux (WSL), or Mac, then installing NodeJS which includes NPM.

The examples are attached to this article as a ZIP archive. Download and decompress this file to a suitable location on your workstation.

Read README.md from the package. Each example here assumes you have already downloaded the package and run npm install; npm run build. The compilation result is placed in the dist directory. For each one of the examples, you simply copy the user-xxxx.css and user-xxxx.js files into the correct object in Advanced Customization.

0151T000003lmB6QAI.png

To make changes to these examples, modify the files in src, then npm run build, as specified in README.md.

Example 1: Decision box with more options

By default, the APM Decision Box has only two choices.

0151T000003lmAyQAI.png

We can use this advanced customization example to append additional choices. Follow this procedure:

  1. Add a decision box to your access policy.
  2. Navigate to customization-examples/dist/decisionBox-more-options and copy the contents of user-decision.js to the appropriate area in Advanced Customization.
  3. 0151T000003lmApQAI.png
  4. Click Save Draft, Save, and apply the access policy.
  5. As a user, navigate to the decision box on the APM virtual server.
  6. 0151T000003lmAqQAI.png
  7. Now the decision box has 4 options rather than two.
  8. The option and icon detail are in the example user-decision.ts source file:
  9. 0151T000003lmAzQAI.png


The result: value is the raw POST data, which is transferred from the client browser when the my.policy page is submitted. It must match an agent expression in the branch rules defined for the decision box object. As with all other agents, the branch rules must be defined in the policy-item configuration so that the additional branches are available in the VPE for use:

0151T000003lmB0QAI.png

Once these additional branch rules are defined, they can be added to the VPE flow:

0151T000003lmBBQAY.png

When a user makes a choice, it appears in log files thusly:

0151T000003lmB7QAI.png

To host your own icons, you can use the APM sandbox hosting feature, discussed elsewhere in this doc.

Example 2: Logon box custom component

This example adds a custom Preact component to the Logon Box.

  1. Add a Logon Page to your access policy, then copy the example dist code into your user-logon.js and user-logon.css files.
  2. 0151T000003lmB8QAI.png
  3. Output:
  4. 0151T000003lmB4QAI.png

 

Example 3: Logon custom view

This is an example of how to obtain a JSON-formatted dump of data available programmatically.

Add the code from logon-custom-view to your APM policy files, then visit the APM virtual. You will see JSON data that provides the detailed data available.

Example 4: PIN Pad replaces standard forms logon page

This is an example of an alternative method of rendering a standard forms logon page with a polymorphic virtual PIN pad. It uses Preact and CSS to achieve this result.

Note: A similar result with a virtual keyboard is possible as well, using other modules available via npm. This requires Preact development.

As with the other examples, compile the TypeScript and place the dist’s user-logon.css and user-logon.js into the APM’s advanced customization area for your logon agent. The result when visiting this logon page is illustrated in this screenshot:

0151T000003lmB5QAI.png
 

Example 5: Validation of input fields

logon-validate-domain contains a sample that has an example of input field validation:

0151T000003lmBCQAY.png

 

The input validation logic can be changed with the following TypeScript:

0151T000003lmB9QAI.png

This kind of validation logic can be extended for almost any purpose.

Example 6: Pin resource to top of webtop

Recently-used-resources implements a mechanism that uses local storage to track how many times a resource has been clicked. It also creates a new webtop section that displays most-clicked-on resources. You must have a full webtop and multiple resources assigned to the user (any type is fine).

Use this example like the others: Copy the dist directory files user-webtop.css and user-webtop.js to the advanced customization object and click Save Draft, then Save, and apply the access policy. Note that you may have to clear BIG-IP or browser cache to see the update.

Take a few minutes to examine the browser's Local Storage contents while clicking various favorites assigned to the user.

0151T000003lmBGQAY.png

Example 7: Pin resources on full webtop

Most application portals offer some kind of system to save often-used resources at the top of the list. This example uses HTML5 Browser Local Storage to save the user’s resources and render them at the top of the webtop application portal. You must assign a full webtop and multiple resources to the user.

Use this example like the others: Copy the dist directory files user-webtop.css and user-webtop.js to the advanced customization object and click Save Draft, then Save, and apply the access policy. Note that you may have to clear BIG-IP or browser cache to see the update.

0151T000003lmBHQAY.png

Afterwards, logon as a user to the webtop and click the corner pin icon to add the resource to Pinned Resources. 

  • Try to log out and back in and see that the resource(s) are saved.
  • Check the browser developer tools to query the local storage contents.

0151T000003lmBAQAY.png

Examples Conclusion

We hope these examples are helpful to performing customization of APM web pages. Please let us know of any further examples that you would like to share!

Request For Examples

We have received the following requests for examples and hope to add these soon. Let us know if you can contribute!

  • Simplest way to add an HTML link and text into the logon page
  • Simplest way to add a select box to a logon page
  • Example virtual keyboard logon page

Attributions / Licensing / Support Status

Support Status:

F5 Support cannot provide assistance with TypeScript, JavaScript, or Preact coding or web development. To validate the operation of any of these examples, standard web development practices should be used.

F5 code:

These examples include code produced by F5 intended to showcase the possibilities of the v15.1.0 APM customization system and can be used by any APM customer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

3rd Party Code:

As with most open source software, each module in this example includes a separate license (MIT, CC, etc). Before using any of these in a production environment, please review the licensing requirements for each NPM package in node_modules.

Media:

Beach scene used in customization examples: Stones in the Beach
By Xavierfsc - Own work, CC BY 4.0, https://commons.wikimedia.org/w/index.php?curid=84430607

 
Comments
Mark_van_D
Cirrostratus
Cirrostratus

Hi Lucas, good article. Should hopefully make things a bit easier to customise APM. I've got a lab running 15.1 but when I try to create a new profile using modern I get the following error.

 

01070712:3: Values (/Common/modern) specified for Customization Group (/Common/mod-test_general_ui): foreign key index (customization_sourceFk) do not point at an item that exists in the database.

ecce
Cirrostratus
Cirrostratus
yuval
Nimbostratus
Nimbostratus

we get errors when try to run npm run build.

no js is created.

cannot use final files

Lucas_Thompson
F5 Employee
F5 Employee

Hi  , thanks for trying this out and sorry you're having problems. The original TGZ archive file was created on a Mac using BSD TAR instead of GNU TAR, and these can have problems when used in some platforms. Please try this second archive that was instead prepared using GNU TAR.

 

http://mail.seattlehq.org/customization-examples2.tgz

 

Because this is hosted on a private server out of F5's control, please checksum the file before use.

 

SHA512SUM:

sha512sum customization-examples2.tgz

 

e2abc0aaccc022640ca0ebd0f20d89d164b95f97953f4589b3c20aff3f33154b9d838c5cb9186da1368004feb2120f6cd31266ff4aaacdd343fec03f78de21d2  customization-examples2.tgz

 

 

Please let us know if this resolves your issue and we'll go ahead and update the original archive.

yuval
Nimbostratus
Nimbostratus

WOW ! thank for your fast replay.

now it was rebuild fine.

i will test it on my modern portal.

 

ThanKs!

Peter_Baumann
Cirrostratus
Cirrostratus

Hi all,

The modern login page and look-and-feel was most often requested by our customers, thank you for this!

 

But... How can a customer migrate a complex apm config to the new modern type without clicking the full apm policy together again?

The effort to create everything again is huge at some customers because they're using many apm policies for different tasks.

 

Thanks,

Peter

Lucas_Thompson
F5 Employee
F5 Employee

 Agreed. This can often be complicated. The primary problem with this is that Modern/Standard use different kinds of customization-group files, and most access policy configuration objects have a customization-group associated with them. The relationship between the objects (start / next-item, etc) are the same between the two though.

You could manually re-assemble a policy like this (by editing the bigip.conf and the filestore customization files) but that is also fairly complicated.

Peter_Baumann
Cirrostratus
Cirrostratus

Hi ,

Thanks for your reply in this.

 

Just today I was talking to a customer which is using guided-configuration.

He also want to use the modern customization type in gc.

I just tested it and it seems that gc is only creating standard customization type as default. Also there's no possibility to go into advanced config and change that at installation time.

 

Do you know the state of the support for gc and modern customization style?

 

Lucas_Thompson
F5 Employee
F5 Employee

Guided Configuration v7 fixed some of these, so if you're running v15.1 or v16.0 and AGC v7.0 it should allow Modern it at least the following sections:

  • IAP
  • SAML IdP
  • Exchange Proxy
  • OAuth AS
  • ADFS proxy
  • OAuth Client/RS

 

If you find it's missing there or if you need that in additional sections, please let us know by opening a support ticket and requesting it.

Peter_Baumann
Cirrostratus
Cirrostratus

Hi  

 

For your information...

 

According to F5 Support, the Modern customization type in AGC will only be supported since v16.0.

 

It is written in the release notes which (shame on me) I was not looking at at first:

https://techdocs.f5.com/kb/en-us/products/big-ip_ltm/releasenotes/product/relnote-bigip-16-0-0.html#...

 

"Guided Configuration now includes modern customization features and the ability to select a previously configured virtual server."

CA_Valli
MVP
MVP

Hello, regarding open request:

  • Simplest way to add an HTML link and text into the logon page

 

I've been answered in this thread with a working example which I wanted to share.

Are any of the examples available on GitHub?

The-messenger
Cirrostratus
Cirrostratus

Is there a document that has the .apmui- options/components?

I'd like to edit the webtop, application link text specifically. Have a background that requires white text to see it, but then I can't see the text in the application link.

Lucas_Thompson
F5 Employee
F5 Employee

Thanks for the question!

To change style related things like this, use CSS. This screenshot illustrates how to use **Inspect** in Chrome's dev tools to figure out the selector and test it. After you test your change, add it to the object's corresponding user-css file in Advanced Customization. 

Lucas_Thompson_0-1643143792630.png

 

 

JacobAx
Nimbostratus
Nimbostratus

Hi Lucas, 

Very helpful stuff,thanks

Could you publish examples how to insert javascript after decisionbox is done rendering same with messageboxes?

papou
Nimbostratus
Nimbostratus

Hi!

How can we adjust the "Execute local javascript code inside Logon Page." general example so we can perform custom actions on full webtop, after browser rendering is complete?
I want to target and add elements inside each apmui-webtop-resource with javascript.

Unfortunately I am not able to find my way through the specific examples you have for webtop.

Thanks!

Jad_Tabbara__J1
Cirrostratus
Cirrostratus

Hello,

Very helpfull thanks.
Just to share with the community the following example that allows you to read a session variable from the "user-logon.js".

In the "standard" customization manner the syntax in the "logon.inc" is:

var plateformOS = "%{session.custom.last.platform}";

In the "modern" way, it is similar you can use in the "user-logon.js" file following:

newDiv.innerHTML = '<img id="os_img" src="%{session.custom.last.platform}" height="30" width="30">';

CCL => same syntax works also in the modern customization

krazzy522
Altocumulus
Altocumulus

Dear 

I need the example code to customize decision box, as same as logon page.

PSilva
Legacy Employee
Legacy Employee

Hi @krazzy522~ Just to let you know, we've contacted the author and he's working on it. He needs to validate the solution before sharing unless other DC Members have the code?

Didn't want to leave you hanging. 🙂

ps

krazzy522
Altocumulus
Altocumulus

Dear PSilva 


I have added div to JS file like below and added CSS to the div

thank you for your time and support

var divlogo = document.createElement("div");
divLogo.id = "logo";
document.body.appendChild(divLogo);
var img = document.createElement("img");
img.setAttribute("src", "logo.png");
divLogo.appendChild(img);

 
PSilva
Legacy Employee
Legacy Employee

We'll pass this on!

ps

kimhenriksen
Cirrostratus
Cirrostratus

Can someone share the templates? The old link is dead.

Version history
Last update:
‎09-Feb-2022 10:07
Updated by: