What is a hosted form?
Introduction
A hosted form is a customized HTML page within Identify Runtime, allowing users to edit HTML, binding, CSS, and JavaScript using REST API or Identify Admin. The content is stored in the SharedConfigurationSettings table. Because of the possible security issues, the hardest part of offering hosted forms is to provide customizations while still making sure that user cannot manipulate any other data from unauthorized access (read, write, delete). The hosted form syntax follows DotLiquid.
Full list of supported hosted forms
Runtime
# | Form name | Original Razor file |
---|---|---|
1 | Login | AuthenticationList.cshtml |
2 | Reset Password | ForgotPasswordPage.cshtml |
3 | My Profile | This is a custom css for my profile page |
4 | Simple Login | UserNamePasswordAuthentication.cshtml |
5 | Error | Error.cshtml |
6 | Report Error | ReportError.cshtml |
7 | Change Password | ChangePassword.cshtml |
8 | Change Password Result | ChangePasswordResult.cshtml |
9 | Renew Password Page | RenewPasswordPage.cshtml |
10 | Renew Password email sent success | RenewPasswordEmailSentSuccess.cshtml |
11 | Renew Password Successfully | RenewPasswordSuccessfully.cshtml |
12 | Renew Password Unsuccessfully | RenewPasswordUnsuccessfully.cshtml |
13 | OTP Malformed Request Error | OtpMalformedRequestError.cshtml |
14 | Enable Authenticator | EnableAuthenticator.cshtml |
15 | Login With Authenticator | LoginWithAuthenticator.cshtml |
16 | OTP Authentication | OtpAuthentication.cshtml |
17 | OTP Authentication Failed | OtpAuthenticationFailed.cshtml |
18 | OS2faktor Device Registration | OS2faktorDeviceRegistration.cshtml |
19 | OS2faktor No Device | OS2faktorNoDevice.cshtml |
20 | OS2faktor User Rejected | OS2faktorUserRejected.cshtml |
21 | OS2faktor Error | OS2faktorError.cshtml |
22 | OS2faktor Pick Device | OS2faktorPickDevice.cshtml |
23 | OS2faktor Login | OS2faktorLogin.cshtml |
24 | Onboarding succeeded | OnboardingSucceeded.cshtml |
25 | Recovery code | RecoveryCode.cshtml |
26 | Enable WebAuthn | EnableWebAuthn.cshtml |
27 | Login With WebAuthn | LoginWithWebAuthn.cshtml |
28 | WebAuthn Error | WebAuthnError.cshtml |
29 | OTP Authentication Server Error | OtpAuthenticationServerError.cshtml |
30 | Enable Device Authentication | EnableDeviceAuthentication.cshtml |
31 | Policy Script Error | PolicyScriptError.cshtml |
32 | Generic Error | GenericError.cshtml |
33 | Restart login | RestartLogin.cshtml |
34 | HRD No Identity Provider Determined | HRDNoIdentityProviderDetermined.cshtml |
35 | First factor web authentication login | FirstFactorLoginWithWebAuthn.cshtml |
36 | First factor input user name | FirstFactorUsername.cshtml |
37 | First factor web authentication login error | FirstFactorWebAuthnError.cshtml |
38 | Delete Coookies | DeleteCookies.cshtml |
39 | Language Chooser | LanguageChooser.cshtml |
IdentifyMe
# | Form name | Original Razor file |
---|---|---|
1 | Home Page | HomePage.cshtml |
2 | My Profile | MyProfile/Index.cshtml |
3 | Certificate | Certificate/Index.cshtml |
4 | Change Password | ChangePassword.cshtml |
5 | Reset Password | ResetPassword.cshtml |
6 | Error Page | Error.cshtml |
7 | Authenticator Administration | AuthenticatorAdministration.cshtml |
8 | Enable Authenticator | EnableAuthenticator.cshtml |
9 | Enable WebAuthn | EnableWebAuthn.cshtml |
10 | WebAuthn Administration | WebAuthnAdministration.cshtml |
11 | Authenticator Onboarding Succeeded | AuthenticatorOnboardingSucceeded.cshtml |
12 | WebAuthn Onboarding Succeeded | WebAuthnOnboardingSucceeded.cshtml |
13 | Access Denied | AccessDenied.cshtml |
You can view more details the IdentifyMe hosted forms at here
Hosted form layout
Customers often need to maintain a consistent look and feel across all the Identify tenant hosted forms. To achieve this, we offer a Liquid site layout that is similar to that of Razor views. The layout is stored in a specific shared configuration name “CustomContent|SiteLayout”:
Layout elements
Elements in the layout are blocks of content for rendering specific views. The hosted form layout currently supports the following elements:
- Title header
{% block "titleheader" %} {{Resources.OtpResources.OtpAuthenticationView_TitleHeader}} {% endblock %}
- Title content
{% block "titlecontent" %} {{Resources.OtpResources.OtpAuthenticationView_TitleContent}} {% endblock %}
- Link to login selector
{% block "linktologinselector" %} //Html content here {% endblock %}
- Sidebar
{% block "sidebar" %} //Sidebar content {% endblock %}
- InitScript
{% block "initscript" %} //Custom initialized javascript code {% endblock %}
- Content
{% block "content" %} //Main form content {% endblock %}
- Scripts
{% block "scripts" %} //Scripts load and execute after HTML content renders {% endblock %}
Using the layout for a specific form is as simple as using the "extends" syntax to inherit the layout:
Common fields
- Captchar image
{{ Captchar }}
- Anti-Forgery Token hidden
{{ Csrf }}
- Copyright info
{{ Copyright }}
Text resource support
All text resources from Identify runtime (and plugins) can be used in hosted forms similar to how we use them in Razor views:
New view engine for hosted form
Behind the scenes, we implemented a new view engine for Liquid views that looks up views from the database. The view engine comprises:
- IFileSystem: Implements the interface to get the liquid template.
- IViewEngine: Implements the engine to render HTML from the liquid template.
- IView: Prepares data model, text resources, and other required data, rendering the view using DotLiquid.
How to add a custom Liquid HTML view to hosted form
Steps to add a new hosted form:
Step 1: Locate the Cshtml view file in Identify Runtime.
Step 2: Transform the model object of that cshtml page into a plain object, simplifying it if needed. Use TypeConverter for complex models.
For example, the original AuthenticationList.cshtml razor view is:
And the model is:
Usually, the Razor view has code that manipulates the model object to compute data. Since you cannot execute C# code in a Liquid view, you need to pre-compute those data in C# code and assign them to a dedicated model object for Liquid view. The computed Liquid model is an anonymous object. To do this, you can use TypeConverter:
The new anonymous object contains everything needed to render a full page of AuthenticationList.
Step 3: The hosted form is an HTML page with Liquid syntax containing all required layout elements. No partial rendering is supported.
The Liquid view engine will look up the custom Liquid viewfrom the SharedConfigurationSettings table by using the key "CustomContent|SignOnAuthenticationList" and render it. The transformed model at step 2 is passed to the Liquid view as a Model object.
Step 4: Run and test for both active and inactive hosted forms.
How to apply a custom hosted using Identify Admin (/admin)
Case study: You want to create a custom AuthenticationList view for each protocol connection (hosted forms currently only support the default view). After you have created a custom Liquid view, you can apply it by following these steps:
- Access Identify Admin.
- Navigate to System Setup > Field Configurator and add a new Field Configuration.
- Name it using this syntax:
- For Runtime: CustomContent|{'viewname'}, e.g., CustomContent|AuthenticationList
- For IdentifyMe: CustomContent|IdentifyMe{'viewname'}, e.g., CustomContent|IdentifyMeHomePage
- Enter Liquid view content in the Content box.
- Set Resource key to "Html" and save the field configuration.
- Open the SAML2.0/OAuth2.0/OpenID Connect application; you will see that your custom view has replaced the default AuthenticationList view.
How to apply a custom hosted using Safewhere Admin
- Access Safwhere Admin and navigate to Hosted forms, then click the + button.
- Enter the Display name and Liquid view content in the HTML content box. Click SAVE button.
- Go back to Settings > System and verify that Show Home Realm Discovery configuration is checked.
- Go back to Applications list and open the SAML2.0/OAuth2.0/OpenID Connect application.
- Open its Home Realm Discovery tab and enter your custom view name in step 6 of Identify Admin, e.g., myapplication1.
Breaking changes
To support liquid template, we must replace ViewBag with ViewData in MVC controller that causes a breaking change on RenewPasswordPage page.
So, updating the Razor view to adapt to the change: