keycloak-scim/server_admin/topics/users/user-profile.adoc

486 lines
No EOL
23 KiB
Text

=== User Profile
In {project_name} a user is associated with a set of attributes. These attributes are used to better describe and identify users within {project_name} as well as to pass over additional information about them to applications.
A user profile defines a well-defined schema for representing user attributes and how they are managed within a realm. By providing a consistent view over user information, it allows administrators to control the different aspects on how attributes are managed as well as to make a lot easier to extend {project_name} to support additional attributes.
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 capabilities are backed by the User Profile SPI. By default, these capabilities are disabled and realms are configured to use a default configuration that keeps backward compatibility with the legacy behavior.
[Note]
====
The legacy behavior is about keeping the default constraints used by {project_name} when managing users root attributes such as username, email, first and last name, without any restriction on how custom attributes are managed. Regarding user flows such as registration, profile update, brokering, and managing accounts through the account console, users are restricted to use the attributes aforementioned with the possibility to change theme templates to support additional attributes.
If you are already using {project_name}, the legacy behavior is what you have been using so far.
====
Differently than the legacy behavior, the declarative provider gives you a lot more flexibility to define the user profile configuration to a realm through the administration console and a well-defined JSON schema.
In the next sections, we'll be looking at how to use the declarative provider to define your own user profile configuration.
[NOTE]
====
In the future, the legacy behavior will no longer be supported on {project_name}. Ideally, you should start looking at the new capabilities provided by the User Profile and migrate your realms accordingly.
====
==== Enabling the User Profile
:tech_feature_name: Declarative User Profile
:tech_feature_setting: -Dkeycloak.profile.feature.declarative_user_profile=enabled
include::../templates/techpreview.adoc[]
In addition to enabling the `declarative_user_profile` feature, you should enable User Profile to a realm. For that, click on the `Realm Settings` link on
the left side menu and then turn on the `User Profile Enabled` switch.
image:images/user-profile-enabling.png[]
Once you enable it and click on the `Save` button, you should be able to access the `User Profile` tab from where you can manage the configuration for user attributes.
By enabling the user profile to a realm, {project_name} is going to impose additional constraints on how attributes are managed based on the user profile configuration. In summary, here is the list of what you should expect when the feature is enabled:
* From an administration point of view, the `Attributes` tab at the user details page will only show the attributes defined in the user profile configuration. The conditions defined on a per-attribute basis will also be taken into account when managing attributes.
* User facing forms like registration, update profile, brokering, and personal info in the account console, are going to be rendered dynamically based on the user profile configuration. For that, {project_name} is going to rely on different templates to render these forms dynamically.
In the next topics, we'll be exploring how to manage the user profile configuration and how does it affect your realm.
==== Managing the User Profile
The user profile configuration is managed on a per-realm basis. For that, click on the
`Realm Settings` link on the left side menu and then click on the `User Profile` tab.
.User Profile Tab
image:images/user-profile-tab.png[]
In the `Attributes` sub-tab you have a list of the attributes currently associated with the user profile. By default, the configuration is created based on the user root attributes and each attribute is configured with some defaults in terms of validation and permissioning.
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.
[NOTE]
====
For now, attribute groups are only used for rendering purposes but in the future they should also enable defining top-level configurations to the attributes they are linked to.
====
In the `JSON Editor` sub-tab you can view and edit the configuration using a well-defined JSON schema. Any change you make when at any other tab should be reflected in the JSON configuration shown at this tab.
In the next section, you are going to learn how to manage the configuration from the `Attributes` sub-tab.
==== Managing Attributes
At the `Attributes` sub-tab you should be able to create, edit, and delete the attributes associated with the user profile.
To define a new attribute and associate it with the user profile, click on the `Create` button in the top-right corner of the attribute listing.
.Attribute Configuration
image:images/user-profile-create-attribute.png[]
When configuring the attribute you should be able to define the following settings:
Name::
The name of the attribute.
Display name::
A user-friendly name for the attribute, mainly used when rendering user-facing forms. It supports internationalization so that values can be loaded from message bundles.
Attribute Group::
The attribute group to which the attribute belongs to, if any.
Enabled when scope::
Allows you to define a list of scopes to dynamically enable an attribute. If not set, the attribute is always enabled and its constraints are always enforced when managing user profiles as well as when rendering user-facing forms. Otherwise, the same constraints only apply when any of the scopes in the list is requested by clients.
Required::
Set the attribute as required. If not enabled, the attribute is optional. Otherwise, the attribute must be provided by users and administrators with the possibility to also make the attribute required only for users or administrators as well as based on the scopes requested by clients.
Permission::
In this section, you can define read and write permissions for users and administrators.
Validation::
In this section, you can define the validations that should be performed when managing the attribute value. {project_name} provides a set of built-in validators you can choose from with the possibility to add your own.
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.
===== Managing Permissions
In the `Permission` section, you can define the level of access users and administrators have to read and write to an attribute.
.Attribute Permission
image:images/user-profile-permission.png[]
For that, you should be able to use the following settings:
Can user view?::
If enabled, users can view the attribute. Otherwise, users don't have access to the attribute.
Can user edit?::
If enabled, users can view and edit the attribute. Otherwise, users don't have access to write to the attribute.
Can admin view?::
If enabled, administrators can view the attribute. Otherwise, administrators don't have access to the attribute.
Can admin edit?::
If enabled, administrators can view and edit the attribute. Otherwise, administrators don't have access to write to the attribute.
[NOTE]
====
When you create an attribute, no permission is set to the attribute. Effectively, the attribute won't be accessible by either users or administrators. Once you create the attribute, make sure to set the permissions accordingly to that the attribute is only visible by the target audience.
====
Permissioning has a direct impact on how and who can manage the attribute, as well as on how the attribute is rendered in user-facing forms.
For instance, by marking an attribute as only viewable by users, the administrators won't have access to the attribute when managing users through the administration console (neither from the User API). Also, users won't be able to change the attribute when updating their profiles. An interesting configuration if user attributes are fetched from an existing identity store (federation) and you just want to make attributes visible to users without any possibility to update the attribute other than through the source identity store.
Similarly, you can also mark an attribute as writable only for administrators with read-only access for users. In this case, only administrators are going to be allowed to manage the attribute.
Depending on your privacy requirements, you might also want attributes inaccessible to administrators but with read-write permissions for users.
Make sure to set the correct permissions whenever you add a new attribute to the user profile configuration.
===== Managing Validations
In the `Validation` section, you can choose from different forms of validation to make sure the attribute value conforms to specific rules.
.Attribute Validation
image:images/user-profile-validation.png[]
{project_name} provides different validators out of the box:
[cols="3*", options="header"]
|===
|Name
|Description
|Configuration
|length
|Check the length of a string value based on a minimum and maximum length.
|
*min*: an integer to define the minimum allowed length.
*max*: an integer to define the maximum allowed length.
*trim-disabled*: a boolean to define whether the value should be trimmed prior to validation.
|integer
|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.
|
*min*: an integer to define the lower range.
*max*: an integer to define the upper range.
|double
|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.
|
*min*: an integer to define the lower range.
*max*: an integer to define the upper range.
|uri
|Check if the value is a valid URI.
| None
|pattern
|Check if the value matches a specific RegEx pattern.
|
*pattern*: the RegEx pattern to use when validating values.
*error-message*: the key of the error message in i18n bundle. If not set a generic message is used.
|email
|Check if the value has a valid e-mail format.
| None
|local-date
|Check if the value has a valid format based on the realm and/or user locale.
| None
|person-name-prohibited-characters
| 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.
|===
===== Managing Annotations
In order to pass additional information to frontends, attributes can be decorated with
annotations to dictate how attributes should be rendered. This capability is mainly useful when extending {project_name} themes to render pages dynamically based on the annotations associated with attributes.
.Attribute Annotation
image:images/user-profile-annotation.png[]
==== Managing Attribute Groups
At the `Attribute Grousp` sub-tab you should be able to 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.
.Attribute Group List
image:images/user-profile-attribute-group-list.png[]
[NOTE]
====
You can't delete attribute groups that are bound to attributes. For that, you should first update the attributes to remove the binding.
====
To create a new group, click on the `Create` button in the top-right corner of the attribute groups listing.
.Attribute Group Configuration
image:images/user-profile-create-attribute-group.png[]
When configuring the group you should be able to define the following settings:
Name::
The name of the group.
Display name::
A user-friendly name for the group, mainly used when rendering user-facing forms. It supports internationalization so that values can be loaded from message bundles.
Display description::
A user-friendly text that should be displayed as a tooltip when rendering user-facing forms.
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.
==== 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.
.JSON Configuration
image:images/user-profile-json-config.png[]
The JSON schema is defined as follows:
[source:json]
----
{
"attributes": [
{
"name": "myattribute",
"required": {
"roles": [ "user", "admin" ],
"scopes": [ "foo", "bar" ]
},
"permissions": {
"view": [ "admin", "user" ],
"edit": [ "admin", "user" ]
},
"validations": {
"email": {},
"length": {
"max": 255
}
},
"annotations": {
"myannotation": "myannotation-value"
}
}
],
"groups": [
{
"name": "personalInfo",
"displayHeader": "Personal Information"
}
]
}
----
The schema supports as many attributes as you need.
For each attribute you should define a `name` and, optionally, the `required`, `permission`, and the `annotations` settings.
===== Required Property
The `required` setting defines whether an attribute is required. {project_name} allows you to set an attribute as required based on different conditions.
When the `required` setting 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 should be 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.
===== Permissions Property
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.
===== Annotations Property
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"]
}
]
}
----
==== Using Dynamic Forms
One of the main capabilities of User Profile is the possibility to dynamically render user-facing forms based on attributes metadata. When you have the feature enabled to your realm, forms like registration and update profile are rendered using specific theme templates to dynamically render pages based on the user profile configuration.
That said, you shouldn't need to customize templates at all if the default rendering mechanisms serves to your needs. In case you still need customizations to themes, here are the templates you should be looking at:
[cols="2*", options="header"]
|===
|Template
|Description
| base/login/update-user-profile.ftl
| The template that renders the update profile page.
| base/login/register-user-profile.ftl
| The template that renders the registration page.
| base/login/idp-review-user-profile.ftl
| The template that renders the page to review/update the user profile when federating users through brokering.
|===
The default rendering mechanism provides the following capabilities:
* Dynamically display fields based on the permissions set to attributes.
* Dynamically render markers for required fields based on the constraints set to the attributes.
* Dynamically render read-only fields depending on the permissions set to an attribute.
* Dynamically order fields depending on the order set to the attributes.
* Dynamically group fields that belong to a same attribute group.
===== Ordering Attributes
The attributes order is set by clicking on the up and down arrows when at the attribute listing page.
.Ordering Attributes
image:images/user-profile-attribute-list-order.png[]
The order you set in this page should be 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 a 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.
====
==== Forcing User Profile Compliance
In order to make sure user profiles are in compliance with the configuration, administrators may use the `VerifyProfile` required action to eventually force users to update their profiles when authenticating to {project_name}.
[NOTE]
====
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.
====
When enabled, the `VerifyProfile` action is going to perform the following steps when the user is authenticating:
* Check whether the user profile is fully compliant with the user profile configuration set to the realm.
* If not, perform an additional step during the authentication so that the user can update any missing or invalid attribute.
* If the user profile is compliant with the configuration, no additional step is performed, and the user continues with the authentication process.
By default, the `VerifyProfile` action is disabled. To enabled it, click on the
`Authentication` link on the left side menu and then click on the `Required Actions` tab. At this tab, click on the `Register` button and select the `VerifyProfile` action.
.Registring the VerifyProfile Required Action
image:images/user-profile-register-verify-profile-action.png[]
==== Migrating to User Profile
Before enabling the User Profile capabilities to a realm, there are some important considerations you should be aware of. By providing a single place to manage attribute metadata, the feature is very strict about the attributes that can be set to users and how they are managed.
In terms of user management, administrators should be able to manage only the attributes defined in the user profile configuration. Any other attribute set to the user and not yet defined in the user profile configuration won't be accessible. It is recommended to update your user profile configuration with all the user attributes you want to expose either to users or administrators.
The same recommendation applies for those accessing the User REST API to query user information.
In regards to {project_name} internal user attributes such as `LDAP_ID`, `LDAP_ENTRY_DN`, or `KERBEROS_PRINCIPAL`, if you want to be able to access those attributes you should have them as attributes in your user profile configuration. The recommendation is to mark these attributes as viewable only to administrators so that you can look at them when managing the user attributes through the administration console or querying users via User API.
In regards to theming, if you already have customizations to the legacy templates (those hardcoded with user root attributes) your custom templates won't be used when rendering user-facing forms but the new templates that render these forms dynamically. Ideally, you should avoid having any customizations to templates and try to stick with the behavior provided by these new templates to dynamically render forms for you. If they are still not enough to address your requirements, you can either customize them or provide us with any feedback so that we discuss whether it makes sense to enhance the new templates.