Hosted forms

What is hosted form

Hosted form is a customized HTML page of Identify Runtime to allow a user to edit HTML, binding, CSS and JavaScript of that page using REST API or Safewhere Admin. Its content is stored in the SharedConfigurationSettings table. Because of the possible security issues, the hardest part of offering hosted forms is to offer customizations while still making sure that user cannot manipulate any other data from unauthorized access (read, write, delete). The hosted form syntax is dotliquid.


Full list of supported hosted forms

# 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

Hosted form layout

Customers typically want to maintain a consistent look and feel across all the hosted forms of an Identify tenant.  For hosted form, we also provide a Liquid site layout which is similar to that of Razor views. The layout is a specific shared configuration name "CustomContent|SiteLayout":


Layout elements

Element in layout is a block of content to render the content from a specific view. Currently, hosted form layout supports the list of elements below:

  • 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 %}

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


Text Resource support

All text resources from Identify runtime (and all plugins) can be used from the hosted form the same way as how we are doing for Razor views:


New View Engine for Hosted form

Behind the scene, we implemented a new view engine for Liquid views which looks up for views from database. The view engine has the following components:

  • IFileSystem: Implement the interface to get the liquid template.
  • IViewEngine: Implement the engine to render html from liquid template.
  • IView: Prepare data model, text resources, other required data and render the view using DotLiquid

How to add a custom Liquid HTML view to hosted form

You can add a new hosted form in 4 steps:

Step 1: Locate the Cshtml view file in Identify Runtime

Step 2: Transform model object of that cshtml page to a plain object. If the transformed model is too complex or has too many dependencies, we must simplify it to only contain necessary data. This can be done by implementing a type converter for the target model.

For an example, the original AuthenticationList.cshtml razor view is:


And the model is:


Usually Razor view has code that manipulates the model object to compute data that is needed by a view. Since you can’t execute C# code in a Liquid view, you need to pre-compute those data in C# code to a dedicated model object for Liquid view. The computed Liquid model is an anonymous object. In order to do that, you can use TypeConverter:


The new anonymous object contains everything needed to render a full page of AuthenticationList.

Step 3: The hosted form is a HTML page with liquid syntax containing all required layout elements to render the page. No partial rendering is supported.
The Liquid view engine will look up for 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: Now you can try to run and test 2 cases: hosted form is active and hosted form does not exist or is inactive.

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 supports the view that is used for all protocol connections by default). After you have created a custom Liquid view, you can apply it by doing the following steps:

  1. Access the Identify Admin site.
  2. Access the System Setup > Field Configurator, and choose to add a new Field Configuration
  3. Name: input the name with the syntax: CustomContent|{viewname}, e.g. CustomContent|AuthenticationList
  4. Expression: enterLiquid view content
  5. Resource key: set it to "Html" and save the field configuration.
  6. Open the SAML2.0 / OAuth2.0/OpenID Connect application, you will see the new AuthenticationList view that you made above replaced for the original AuthenticationList view.

How to apply a custom hosted using Safewhere Admin

  1. Access the Safewhere Admin site.
  2. Access the Settings\Field Configurator, and choose to add a new Field Configuration
    • Name: input the name with the syntax: CustomContent|{viewname}, e.g CustomContent|myapplication1
    • Expression: enter Liquid view content
    • Resource key: set it to "Html" . Then save the field configuration.
  3. Access the Settings\System, verify the setting: Show Home Realm Discovery configuration is True
  4. Access the Application list, open the SAML2.0 / OAuth2.0/OpenID Connect application.
  5. Access its Home Realm Discovery tab, enter the view name to the "Authentication list view name" setting, e.g inthis sample, it is "myapplication1"

Breaking changes

To support liquid template, we must get rid of using "ViewBag" from MVC controller that causes a breaking change on "RenewPasswordPage". The ViewData object is used instead.


So, the Razor view should be updated to adapt to the change: