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 and its content is stored in the SharedConfigurationSettings table. Because of security issue, the hardest part of hosted form is allowed user to custom a page, but don’t allow him to manipulate any other data from unauthorized access (read, write, delete). The hosted form syntax is dotliquid.


The 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 Enable WebAuthn EnableWebAuthn.cshtml
25 Login With WebAuthn LoginWithWebAuthn.cshtml
26 WebAuthn Error WebAuthnError.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" %}


{% endblock %}

  • Title content

{% block "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

For now, 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 customize liquid html view to hosted form

You can add new hosted form in 4 steps:

Step 1: Locate 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, thoriginal 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 view from 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 for 2 cases: hosted form is active, and hosted form doesn’t exist or is inactive.

How to apply a custom hosted form 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: enter Liquid 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 form 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: