Among other capabilities, user profile enables administrators to:
* Define a schema for user attributes
* Define whether an attribute is required based on contextual information (e.g.: if required only for users, or admins, or both, or depending on the scope being requested.)
* Define specific permissions for viewing and editing user attributes, making possible to adhere to strong privacy requirements where some attributes can not be seen or be changed by third-parties (including administrators)
* Dynamically enforce user profile compliance so that user information is always updated and in compliance with the metadata and rules associated with attributes
* Define validation rules on a per-attribute basis by leveraging the built-in validators or writing custom ones
* Dynamically render forms that users interact with like registration, update profile, brokering, and personal information in the account console, according to the attribute definitions and without any need to manually change themes.
The user profile schema or configuration uses a <<_user-profile-json-configuration,JSON>> format to represent attributes and their metadata. From the administration console,
you are able to manage the configuration by clicking on the `Realm Settings` on the left side menu and then clicking on the `User Profile` tab on that page.
As you will see in the following sections, you might restrict certain attributes to be available only from the administrative context and disable them
completely for end-users. The other way around is also true if you don't want administrators to have access to certain user attributes but only the end-user.
* *Managed*. These are attributes controlled by your user profile, to which you want to allow end-users and administrators
to manage from any user profile context.
For these attributes, you want complete control on how and when they are managed.
* *Unmanaged*. These are attributes you do not explicitly define in your user profile so that they are completely ignored by {project_name}, by default.
Although unmanaged attributes are disabled by default, you can configure your realm using different policies to define how they are handled by the server.
For that, click on the `Realm Settings` at the left side menu, click on the `General` tab, and then choose any of the following options from the `Unmanaged Attributes` setting:
* *Disabled*. This is the default policy so that unmanaged attributes are disabled from all user profile contexts.
* *Enabled*. This policy enables unmanaged attributes to all user profile contexts.
* *Admin can view*. This policy enables unmanaged attributes only from the administrative context as read-only.
* *Admin can edit*. This policy enables unmanaged attributes only from the administrative context for reads and writes.
These policies give you a fine-grained control over how the server will handle unmanaged attributes.
You can choose to completely disable or only support unmanaged attributes when managing users through the administrative context.
When unmanaged attributes are enabled (even if partially) you can manage them from the administration console at the `Attributes` tab in the User Details UI.
If the policy is set to `Disabled` this tab is not available.
attributes (and values) set to your users when they are managing their profile through end-user contexts.
Avoid setting the `Enabled` policy and prefer defining all the attributes that end-users can manage in your user profile configuration, under your control.
[NOTE]
====
The `Enabled` policy is targeted for realms migrating from previous versions of {project_name} and to avoid breaking
behavior when using custom themes and extending the server with their own custom user attributes.
====
As you will see in the following sections, you can also restrict the audience for an attribute by choosing if it should be visible or writable by users and/or administrators.
In the `Attribute Groups` sub-tab you can manage attribute groups. An attribute group allows you to correlate attributes so that they are displayed together when rendering user facing forms.
A user-friendly name for the attribute, mainly used when rendering user-facing forms. It also supports link:#_using-internationalized-messages[Using Internationalized Messages]
In this section, you can associate annotations to the attribute. Annotations are mainly useful to pass over additional metadata to frontends for rendering purposes.
When you create an attribute, the attribute is only available from administrative contexts to avoid unexpectedly exposing attributes to end-users.
Effectively, the attribute won't be accessible to end-users when they are managing their profile through the end-user contexts. You can change the `Permissions` settings anytime accordingly
|Check if the value is an integer and within a lower and/or upper range. If no range is defined, the validator only checks whether the value is a valid number.
|Check if the value is a double and within a lower and/or upper range. If no range is defined, the validator only checks whether the value is a valid number.
| Check if the value is a valid person name as an additional barrier for attacks such as script injection. The validation is based on a default RegEx pattern that blocks characters not common in person names.
|
*error-message*: the key of the error message in i18n bundle. If not set a generic message is used.
|username-prohibited-characters
| Check if the value is a valid username as an additional barrier for attacks such as script injection. The validation is based on a default RegEx pattern that blocks characters not common in usernames.
|
*error-message*: the key of the error message in i18n bundle. If not set a generic message is used.
|The field can contain only latin characters and common unicode characters. Useful for the fields, which can be subject of IDN homograph attacks (typically username).
|
*error-message*: the key of the error message in i18n bundle. If not set a generic message is used.
Annotations are used, for example, for link:#_changing-the-html-type-for-an-attribute[Changing the HTML `type` for an Attribute] and link:#_changing-the-dom-representation-of-an-attribute[Changing the DOM representation of an Attribute], as you will
|Helper text rendered before (above) the input field. Direct text or internationalization pattern (like `${i18n.key}`) can be used here.
Text is NOT html escaped when rendered into the page, so you can use html tags here to format the text, but you also have to correctly escape html control characters.
Text is NOT html escaped when rendered into the page, so you can use html tags here to format the text, but you also have to correctly escape html control characters.
|inputOptionsFromValidation
|Annotation for select and multiselect types. Optional name of custom attribute validation to get input options from. See link:#_managing_options_for_select_fields[detailed description] below.
|inputOptionLabelsI18nPrefix
|Annotation for select and multiselect types. Internationalization key prefix to render options in UI. See link:#_managing_options_for_select_fields[detailed description] below.
|inputOptionLabels
|Annotation for select and multiselect types. Optional map to define UI labels for options (directly or using internationalization). See link:#_managing_options_for_select_fields[detailed description] below.
|HTML input `placeholder` attribute applied to the field - specifies a short hint that describes the expected value of an input field (e.g. a sample value
|HTML input `size` attribute applied to the field - specifies the width, in characters, of a single line input field. For fields based on HTML `select` type
it specifies number of rows with options shown. May not work, depending on css in used theme!
|inputTypeCols
|HTML input `cols` attribute applied to the field - specifies the width, in characters, for `textarea` type. May not work, depending on css in used theme!
|HTML input `maxlength` attribute applied to the field providing client side validation - maximal length of the text which can be entered into the input
|HTML input `minlength` attribute applied to the field providing client side validation - minimal length of the text which can be entered into the input
|If set, the `data-kcNumberFormat` attribute is added to the field to format the value based on a given format. This annotation is targeted for numbers where the format is based on the
number of digits expected in a determined position. For instance, a format `(\{2}) \{5}-\{4}` will format the field value to `(00) 00000-0000`.
|Number UnFormat
|If set, the `data-kcNumberUnFormat` attribute is added to the field to format the value based on a given format before submitting the form. This annotation
is useful if you do not want to store any format for a specific attribute but only format the value on the client side. For instance, if the current value
is `(00) 00000-0000`, the value will change to `00000000000` if you set the value `\{11}` to this annotation or any other format you want by specifying a set of one or ore group of digits.
Make sure to add validators to perform server-side validations before storing values.
option value (defined in validation), and value in the map is UI label text itself or its internationalization pattern (like `${i18n.key}`) for that option.
For instance, if you add a `kcMyCustomValidation` annotation to an attribute, the HTML attribute `data-kcMyCustomValidation` is added to
the corresponding HTML element for the attribute, and a JavaScript module is loaded from your custom theme at `<THEME TYPE>/resources/js/kcMyCustomValidation.js`.
See the {developerguide_link}[{developerguide_name}] for more information about how to deploy a custom JavaScript module to your theme.
The JavaScript module can run any code to customize the DOM and the elements rendered for each attribute. For that,
you can use the `userProfile.js` module to register an annotation descriptor for your custom annotation as follows:
[source,javascript]
----
import { registerElementAnnotatedBy } from "./userProfile.js";
registerElementAnnotatedBy({
name: 'kcMyCustomValidation',
onAdd(element) {
var listener = function (event) {
// do something on keyup
};
element.addEventListener("keyup", listener);
// returns a cleanup function to remove the event listener
At the `Attribute Groups` sub-tab you can create, edit, and delete attribute groups. An attribute group allows you to define a container for correlated attributes so that they are rendered together when at the user-facing forms.
When configuring the group you can define the following settings:
Name::
The name of the attribute, used to uniquely identify an attribute.
Display name::
A user-friendly name for the attribute, mainly used when rendering user-facing forms. It also supports link:#_using-internationalized-messages[Using Internationalized Messages]
Display description::
A user-friendly text that will be displayed as a tooltip when rendering user-facing forms. It also supports link:#_using-internationalized-messages[Using Internationalized Messages]
Annotation::
In this section, you can associate annotations to the attribute. Annotations are mainly useful to pass over additional metadata to frontends for rendering purposes.
[[_user-profile-json-configuration]]
== Using the JSON configuration
The user profile configuration is stored using a well-defined JSON schema. You can choose from editing the user profile configuration directly by clicking on the `JSON Editor` sub-tab.
The schema supports as many attributes and groups as you need.
The `unmanagedAttributePolicy` property defines the unmanaged attribute policy by setting one of following values. For more details,
look at the link:#_understanding-managed-and-unmanaged-attributes[Understanding Managed and Unmanaged Attributes].
* `DISABLED`
* `ENABLED`
* `ADMIN_VIEW`
* `ADMIN_EDIT`
=== Attribute Schema
For each attribute you should define a `name` and, optionally, the `required`, `permission`, and the `annotations` settings.
The `required` property defines whether an attribute is required. {project_name} allows you to set an attribute as required based on different conditions.
When the `required` property is defined as an empty object, the attribute is always required.
[source,json]
----
{
"attributes": [
{
"name": "myattribute",
"required": {}
]
}
----
On the other hand, you can choose to make the attribute required only for users, or administrators, or both. As well as mark the attribute as required only in case a specific scope is requested when the user is authenticating in {project_name}.
To mark an attribute as required for a user and/or administrator, set the `roles` property as follows:
[source,json]
----
{
"attributes": [
{
"name": "myattribute",
"required": {
"roles": ["user"]
}
]
}
----
The `roles` property expects an array whose values can be either `user` or `admin`, depending on whether the attribute is required by the user or the administrator, respectively.
Similarly, you can choose to make the attribute required when a set of one or more scopes is requested by a client when authenticating a user. For that, you can use the `scopes` property as follows:
[source,json]
----
{
"attributes": [
{
"name": "myattribute",
"required": {
"scopes": ["foo"]
}
]
}
----
The `scopes` property is an array whose values can be any string representing a client scope.
The attribute-level `permissions` property can be used to define the read and write permissions to an attribute. The permissions are set based on whether these operations can be performed on the attribute by a user, or administrator, or both.
[source,json]
----
{
"attributes": [
{
"name": "myattribute",
"permissions": {
"view": ["admin"],
"edit": ["user"]
}
]
}
----
Both `view` and `edit` properties expect an array whose values can be either `user` or `admin`, depending on whether the attribute is viewable or editable by the user or the administrator, respectively.
When the `edit` permission is granted, the `view` permission is implicitly granted.
The attribute-level `annotation` property can be used to associate additional metadata to attributes. Annotations are mainly useful for passing over additional information about attributes to frontends rendering user attributes based on the user profile configuration. Each annotation is a key/value pair.
[source,json]
----
{
"attributes": [
{
"name": "myattribute",
"annotations": {
"foo": ["foo-value"],
"bar": ["bar-value"]
}
]
}
----
=== Attribute Group Schema
For each attribute group you should define a `name` and, optionally, the `annotations` settings.
The attribute-level `annotation` property can be used to associate additional metadata to attributes. Annotations are mainly useful for passing over additional information about attributes to frontends rendering user attributes based on the user profile configuration. Each annotation is a key/value pair.
== Customizing How UIs are Rendered
The UIs from all the user profile contexts (including the administration console) are rendered dynamically accordingly to your
user profile configuration.
The default rendering mechanism provides the following capabilities:
* Show or hide fields based on the permissions set to attributes.
* Render markers for required fields based on the constraints set to the attributes.
* Change the field input type (text, date, number, select, multiselect) set to an attribute.
* Mark fields as read-only depending on the permissions set to an attribute.
* Order fields depending on the order set to the attributes.
* Group fields that belong to the same attribute group.
* Dynamically group fields that belong to the same attribute group.
=== Ordering attributes
The attribute order is set by dragging and dropping the attribute rows on the attribute listing page.
The order you set in this page is respected when fields are rendered in dynamic forms.
=== Grouping attributes
When dynamic forms are rendered, they will try to group together attributes that belong to the same attribute group.
.Dynamic Update Profile Form
image:images/user-profile-update-profile.png[]
[NOTE]
====
When attributes are linked to an attribute group, the attribute order is also important to make sure attributes within the same group are close together, within a same group header. Otherwise, if attributes within a group do not have a sequential order you might have the same group header rendered multiple times in the dynamic form.
====
== Enabling Progressive Profiling
In order to make sure end-user profiles are in compliance with the configuration, administrators can use the `VerifyProfile` required action to eventually force users to update their profiles when authenticating to {project_name}.
The `VerifyProfile` action is similar to the `UpdateProfile` action. However, it leverages all the capabilities provided by the user profile to automatically enforce compliance with the user profile configuration.
The `VerifyProfile` action is enabled by default. To disable it, click on the
`Authentication` link on the left side menu and then click on the `Required Actions` tab. At this tab, use the *Enabled* switch of the `VerifyProfile` action to disable it.
For that, you can use a placeholder to resolve messages keys such as `${myAttributeName}`, where `myAttributeName` is the key for a message in a message bundle. For more details,
look at link:{developerguide_link}#messages[{developerguide_name}] about how to add message bundles to custom themes.