|
| 1 | +# Extended UI |
| 2 | + |
| 3 | +You can extend the login user interface (UI) flow with custom login pages build with dynamic elements. The extended UIs have full support for culture / multi language. |
| 4 | +It is possible to create multiple custom UIs with different dynamic elements. |
| 5 | +Each extended UI page can optionally [call an API](#implement-api). If an API is called the returned claims is added to the claims collection otherwise the input values is added as the output claim type defined on the dynamic elements. |
| 6 | + |
| 7 | +The dynamic elements consist of fixed fields a customisable field and both text and HTML content elements. With this you can easily ask for the user's name, one or more self defined fields and show a logo and a link on a extended UI page. |
| 8 | + |
| 9 | +> Extended UIs can be added to the following authentication methods in the **Extended UI** tab; login, external login, OpenID Connect, SAML 2.0 and environment link. |
| 10 | +
|
| 11 | +**Select extended UI page** |
| 12 | +You select an extended UI page in the login flow by adding the claim type `open_extended_ui` with the extended UI page name in the first-level claim transforms. |
| 13 | +In a SAML 2.0 authentication method optionally select with the corresponding SAML 2.0 claim `http://schemas.foxids.com/ws/identity/claims/openextendedui` in the first-level claim transforms. |
| 14 | +Subsequently extended UI pages can be selected in the extended UI claim transforms by adding the claim type `open_extended_ui` (JWT claim only) with the next extended UI page name. |
| 15 | + |
| 16 | +**Example** |
| 17 | +This example page asks the user to enter their social security number (shown in two languages). |
| 18 | +The example extended UI adds the input value to the claims collection as the claim type `social_security_number`. In a real-world scenario, you would probably call an API to validate the social security number. |
| 19 | +In English: |
| 20 | + |
| 21 | + |
| 22 | +In Danish: |
| 23 | + |
| 24 | + |
| 25 | +The example page is configured in a SAML 2.0 authentication method with three elements. |
| 26 | + |
| 27 | + |
| 28 | + |
| 29 | +> The extended UI can be customised with CSS in the login authentication method called **Default login**, unless you create another login method and use that instead. There's quite a lot of flexibility in how the dialogs can be designed. |
| 30 | +
|
| 31 | +## Translations |
| 32 | +The texts (and error messages) used in dynamic elements is automatically translated if they are defined as global text with translations. Otherwise, there is automatically created a text element in the environments on winch you can add translations. |
| 33 | +If you want to support multi languages, you should create the texts as English texts and add translations for the texts. |
| 34 | + |
| 35 | +You find the texts and translations in the **Settings** tab and then the **Texts** tab. |
| 36 | + |
| 37 | + |
| 38 | +## Implement API |
| 39 | + |
| 40 | +Each extended UI page can [call an API](#implement-api) with the result from the dynamic elements and selected claims. The API can then validate the user input and either on success return claims or an error message to the user. |
| 41 | + |
| 42 | +You need to implement a simple API that FoxIDs calls on every page request. |
| 43 | +Please have a look at the [sample code](#api-sample). |
| 44 | + |
| 45 | +The API has a base URL, and the functionality is divided into folders. Currently, only the `validate` folder (functionality) for validating the dynamic elements and selected claims is support. |
| 46 | +*Other folders may be added later.* |
| 47 | + |
| 48 | +If the base URL for the API is `https://somewhere.org/mystore` the URL for the `validate` folder will be `https://somewhere.org/mystore/validate`. |
| 49 | + |
| 50 | +> FoxIDs Cloud calls your API from the IP address `57.128.60.142`. |
| 51 | + *The outgoing IP address can be changed and more can be added over time.* |
| 52 | + |
| 53 | +### Request |
| 54 | +The API call is secured with [HTTP Basic authentication scheme](https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1) where FoxIDs sends the ID `external_extended_ui` as the username and the configured secret as the password. |
| 55 | + |
| 56 | +The API is called with HTTP POST and a JSON body. |
| 57 | + |
| 58 | +This is a request JSON body with two dynamic elements and two claims: |
| 59 | +```JSON |
| 60 | +{ |
| 61 | + "elements": [ |
| 62 | + { |
| 63 | + "Name": "ne5uqp5z", |
| 64 | + "Type": "Email", |
| 65 | + "ClaimType": "email", |
| 66 | + |
| 67 | + }, |
| 68 | + { |
| 69 | + "Name": "ktvywqwc", |
| 70 | + "Type": "Custom", |
| 71 | + "ClaimType": "my_claim", |
| 72 | + "Value": "123456" |
| 73 | + } |
| 74 | + ], |
| 75 | + "claims": [ |
| 76 | + { |
| 77 | + "type": "sub", |
| 78 | + "value": "1b1ac05e-5937-4939-a49c-0e84a89662df" |
| 79 | + }, |
| 80 | + { |
| 81 | + "type": "email", |
| 82 | + |
| 83 | + } |
| 84 | + ] |
| 85 | +} |
| 86 | +``` |
| 87 | + |
| 88 | +### Response |
| 89 | +**Success** |
| 90 | +On success the API should return HTTP code 200 and a list of `claims` (the list can be empty). |
| 91 | + |
| 92 | +For example, the valid input values as claims: |
| 93 | +```JSON |
| 94 | +{ |
| 95 | + "claims": [ |
| 96 | + { |
| 97 | + "type": "email", |
| 98 | + |
| 99 | + }, |
| 100 | + { |
| 101 | + "type": "my_claim", |
| 102 | + "value": "123456" |
| 103 | + } |
| 104 | + ] |
| 105 | +} |
| 106 | +``` |
| 107 | + |
| 108 | +**Error** |
| 109 | +The API must return HTTP code 401 (Unauthorized) and an `error` (required) if the Basic authentication is rejected. Optionally add an error description in `ErrorMessage`. |
| 110 | +```JSON |
| 111 | +{ |
| 112 | + "error": "invalid_api_id_secret", |
| 113 | + "ErrorMessage": "Invalid API ID or secret" |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | + |
| 118 | +The API can return HTTP code 400 (401 and 403 is also supported), and an `error` (required) if the input is rejected. Optionally add an error message to the user in `UiErrorMessage` and an error description in `ErrorMessage`. |
| 119 | +The `UiErrorMessage` is translated as a text and should be in English if you want to support multi languages. |
| 120 | + |
| 121 | +A general validation error: |
| 122 | +```JSON |
| 123 | +{ |
| 124 | + "error": "invalid", |
| 125 | + "ErrorMessage": "Something is not accepted.", |
| 126 | + "UiErrorMessage": "Please change the thing that is wrong." |
| 127 | +} |
| 128 | +``` |
| 129 | + |
| 130 | +A validation error connected to a dynamic element by the elements name: |
| 131 | +```JSON |
| 132 | +{ |
| 133 | + "error": "invalid", |
| 134 | + "elements": [ |
| 135 | + { |
| 136 | + "Name": "ktvywqwc", |
| 137 | + "ErrorMessage": "The element is not valid because of something.", |
| 138 | + "UiErrorMessage": "Please change the value to the correct value." |
| 139 | + } |
| 140 | + ] |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +If other errors occur, the API should return HTTP code 500 or another appropriate error code. |
| 145 | +It is recommended to add a technical error message in `ErrorMessage`. The error message can then later be found in the FoxIDs logs. |
| 146 | + |
| 147 | +> Error messages returned from the API in `ErrorMessage` is NOT displayed for the user only logged. |
| 148 | +
|
| 149 | +## API Sample |
| 150 | +The sample [ExternalExtendedUiApiSample](https://github.com/ITfoxtec/FoxIDs.Samples/tree/main/src/ExternalExtendedUiApiSample) show how to implement the API in ASP.NET Core. |
| 151 | + |
| 152 | +You can user this [Postman collection](https://github.com/ITfoxtec/FoxIDs.Samples/tree/main/src/ExternalExtendedUiApiSample/external-extended-ui-api.postman_collection.json) to call and test your API with [Postman](https://www.postman.com/downloads/). |
| 153 | + |
| 154 | +## Configure |
| 155 | +Configure an extended UI page in a authentication method to call your API in [FoxIDs Control Client](control.md#foxids-control-client). |
| 156 | + |
| 157 | +Navigate the **Authentication** tab and select the authentication method, then select the **Extended UI** tab. Find the extended UI page and configure the API. |
| 158 | + |
| 159 | + |
| 160 | + |
| 161 | +- Optionally select claims that should be send to the API. |
| 162 | +- Add the base API URL without the `validate` folder in **API URL** |
| 163 | +- Add the **API secret** |
| 164 | +- Add a generic error message which is displayed for the user if the API returns an error without a `UiErrorMessage` |
0 commit comments