You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2025/05/30 09:29:37 UTC

(syncope) branch master updated: [SYNCOPE-1887] Require re-auth for sensitive features (#1097)

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 8f262b65ee [SYNCOPE-1887] Require re-auth for sensitive features (#1097)
8f262b65ee is described below

commit 8f262b65ee1e6400f94f8784a33bcf06529dc756
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Fri May 30 11:26:58 2025 +0200

    [SYNCOPE-1887] Require re-auth for sensitive features (#1097)
---
 .../apache/syncope/client/console/pages/SRA.java   |   2 +-
 .../apache/syncope/client/console/pages/WA.java    |   2 +-
 .../syncope/client/enduser/pages/AuthProfile.java  |  59 +++++----
 .../client/enduser/rest/AuthProfileRestClient.java |   7 +-
 .../client/console/topology/TabularTopology.java   |   2 +-
 .../syncope/client/console/topology/Topology.java  |   2 +-
 .../syncope/client/ui/commons/BaseLogin.java       |  29 +++--
 .../client/ui/commons}/annotations/AMPage.java     |   2 +-
 .../client/ui/commons}/annotations/IdMPage.java    |   2 +-
 .../ui/commons/panels/BaseSSOLoginFormPanel.java   |   6 +
 .../init/ClassPathScanImplementationLookup.java    |   4 +-
 .../syncope/client/console/pages/BasePage.java     |   4 +-
 .../apache/syncope/client/console/pages/Login.java |   5 +-
 .../enduser/BookmarkablePageLinkBuilder.java       |   5 +-
 .../syncope/client/enduser/EnduserProperties.java  |  10 ++
 .../client/enduser/SyncopeEnduserSession.java      |  26 +++-
 .../client/enduser/SyncopeWebApplication.java      |   5 +
 .../client/enduser/commons/EnduserConstants.java   |   8 +-
 .../init/ClassPathScanImplementationLookup.java    |  31 +++++
 .../client/enduser/layout/SidebarLayout.java       |   1 -
 .../enduser/pages/AbstractChangePassword.java      |   4 +-
 .../syncope/client/enduser/pages/BaseExtPage.java  |   4 -
 .../syncope/client/enduser/pages/BasePage.java     |  24 +---
 .../client/enduser/pages/BaseReauthPage.java       |  51 ++++++++
 .../client/enduser/pages/EditChangePassword.java   |  21 ++--
 .../client/enduser/pages/EditSecurityQuestion.java |   2 +-
 .../syncope/client/enduser/pages/EditUser.java     |   2 +-
 .../apache/syncope/client/enduser/pages/Login.java |  30 +++--
 .../client/enduser/pages/MustChangePassword.java   |   5 +
 .../syncope/client/enduser/pages/ReauthLogin.java  |  64 ++++++++++
 .../syncope/client/enduser/panels/Sidebar.java     |  88 +++++++++++--
 .../client/enduser/panels/UserFormPanel.java       |   7 +-
 .../client/enduser/rest/SyncopeRestClient.java     |   9 +-
 .../client/enduser/widgets/UserProfileWidget.java  |   4 -
 .../enduser/src/main/resources/enduser.properties  |   1 +
 .../enduser/SyncopeEnduserApplication.properties   |   4 +-
 .../SyncopeEnduserApplication_fr_CA.properties     |   4 +-
 .../SyncopeEnduserApplication_it.properties        |  18 +--
 .../SyncopeEnduserApplication_ja.properties        |   4 +-
 .../SyncopeEnduserApplication_pt_BR.properties     |   2 +-
 .../SyncopeEnduserApplication_ru.properties        |   4 +-
 ...itUser.properties => BaseReauthPage.properties} |   8 +-
 ...ser.properties => BaseReauthPage_fr.properties} |   8 +-
 ...ser.properties => BaseReauthPage_it.properties} |   8 +-
 ...ser.properties => BaseReauthPage_ja.properties} |   8 +-
 ....properties => BaseReauthPage_pt_BR.properties} |   8 +-
 ...ser.properties => BaseReauthPage_ru.properties} |   8 +-
 .../enduser/pages/EditChangePassword.properties    |   2 -
 .../pages/EditChangePassword_fr_CA.properties      |   2 -
 .../enduser/pages/EditChangePassword_it.properties |   2 -
 .../enduser/pages/EditChangePassword_ja.properties |   2 -
 .../pages/EditChangePassword_pt_BR.properties      |   2 -
 .../enduser/pages/EditChangePassword_ru.properties |   3 -
 .../enduser/pages/EditSecurityQuestion.properties  |   4 +-
 .../pages/EditSecurityQuestion_it.properties       |   4 +-
 .../pages/EditSecurityQuestion_ja.properties       |   4 +-
 .../pages/EditSecurityQuestion_pt_BR.properties    |   3 +-
 .../pages/EditSecurityQuestion_ru.properties       |   5 +-
 .../syncope/client/enduser/pages/EditUser.html     |  20 +--
 .../client/enduser/pages/EditUser.properties       |   4 -
 .../enduser/pages/MustChangePassword.properties    |   3 -
 .../enduser/pages/MustChangePassword_it.properties |   4 -
 .../enduser/pages/MustChangePassword_ja.properties |   4 -
 .../pages/MustChangePassword_pt_BR.properties      |   2 -
 .../enduser/pages/MustChangePassword_ru.properties |   5 -
 .../pages/SelfConfirmPasswordReset.properties      |   2 -
 .../pages/SelfConfirmPasswordReset_it.properties   |   2 -
 .../pages/SelfConfirmPasswordReset_ja.properties   |   2 -
 .../SelfConfirmPasswordReset_pt_BR.properties      |   2 -
 .../pages/SelfConfirmPasswordReset_ru.properties   |   2 -
 .../SelfPasswordReset$SelfPwdResetPanel.properties |   2 -
 ...asswordReset$SelfPwdResetPanel_fr_CA.properties |   2 -
 ...lfPasswordReset$SelfPwdResetPanel_it.properties |   2 -
 ...lfPasswordReset$SelfPwdResetPanel_ja.properties |   2 -
 ...asswordReset$SelfPwdResetPanel_pt_BR.properties |   2 -
 ...lfPasswordReset$SelfPwdResetPanel_ru.properties |   2 -
 .../enduser/panels/ChangePasswordPanel.properties  |   3 -
 .../panels/ChangePasswordPanel_it.properties       |   2 -
 .../panels/ChangePasswordPanel_ja.properties       |   2 -
 .../panels/ChangePasswordPanel_pt_BR.properties    |   2 -
 .../panels/ChangePasswordPanel_ru.properties       |   3 -
 .../syncope/client/enduser/panels/Sidebar.html     | 136 +++++++++++----------
 .../enduser/panels/any/UserDetails.properties      |   2 +-
 .../enduser/panels/any/UserDetails_it.properties   |   2 +-
 .../enduser/panels/any/UserDetails_ja.properties   |   2 +-
 .../panels/any/UserDetails_pt_BR.properties        |   2 +-
 .../enduser/panels/any/UserDetails_ru.properties   |   2 +-
 .../client/enduser/widgets/UserProfileWidget.html  |  58 ++++-----
 .../src/test/resources/enduser-debug.properties    |   4 +-
 .../panels/AbstractOIDCSSOLoginFormPanel.java      |  10 +-
 .../ui/commons/panels/OIDCC4UIConstants.java       |   2 +
 .../commons/resources/oidcc4ui/LoginResource.java  |  11 +-
 .../client/enduser/pages/OIDCClientLogin.java      |   2 +
 .../apache/syncope/core/logic/OIDCC4UILogic.java   |  20 ++-
 .../common/rest/api/service/OIDCC4UIService.java   |   5 +-
 .../core/rest/cxf/service/OIDCC4UIServiceImpl.java |   4 +-
 .../client/ui/commons/SAML2SP4UIConstants.java     |   2 +
 .../panels/AbstractSAMLSSOLoginFormPanel.java      |  11 +-
 .../resources/saml2sp4ui/LoginResource.java        |   4 +-
 .../syncope/client/enduser/pages/SAML2SPLogin.java |   2 +
 .../apache/syncope/core/logic/SAML2SP4UILogic.java |  41 +++----
 .../common/rest/api/service/SAML2SP4UIService.java |   9 +-
 .../rest/cxf/service/SAML2SP4UIServiceImpl.java    |   5 +-
 103 files changed, 616 insertions(+), 441 deletions(-)

diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java
index 43bf65ab19..96bc50229f 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java
@@ -23,13 +23,13 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.annotations.AMPage;
 import org.apache.syncope.client.console.panels.AMSessionPanel;
 import org.apache.syncope.client.console.panels.SRARouteDirectoryPanel;
 import org.apache.syncope.client.console.panels.SRAStatisticsPanel;
 import org.apache.syncope.client.console.rest.SRARouteRestClient;
 import org.apache.syncope.client.console.rest.SRASessionRestClient;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.annotations.AMPage;
 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
 import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
 import org.apache.syncope.common.lib.types.AMEntitlement;
diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java
index 88dd368310..4692d97c5a 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java
@@ -32,7 +32,6 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.SyncopeWebApplication;
-import org.apache.syncope.client.console.annotations.AMPage;
 import org.apache.syncope.client.console.authprofiles.AuthProfileDirectoryPanel;
 import org.apache.syncope.client.console.clientapps.ClientApps;
 import org.apache.syncope.client.console.panels.AMSessionPanel;
@@ -50,6 +49,7 @@ import org.apache.syncope.client.console.rest.WAConfigRestClient;
 import org.apache.syncope.client.console.rest.WASessionRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.lib.WebClientBuilder;
+import org.apache.syncope.client.ui.commons.annotations.AMPage;
 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
 import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
 import org.apache.syncope.common.lib.types.AMEntitlement;
diff --git a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java
index 8a1a08a020..50a584d4f8 100644
--- a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java
+++ b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java
@@ -19,11 +19,10 @@
 package org.apache.syncope.client.enduser.pages;
 
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
 import org.apache.syncope.client.enduser.rest.AuthProfileRestClient;
 import org.apache.syncope.client.ui.commons.Constants;
-import org.apache.syncope.client.ui.commons.annotations.ExtPage;
+import org.apache.syncope.client.ui.commons.annotations.AMPage;
 import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink;
 import org.apache.syncope.common.lib.to.AuthProfileTO;
 import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount;
@@ -41,8 +40,8 @@ import org.apache.wicket.markup.repeater.data.ListDataProvider;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
-@ExtPage(label = "Auth Profile", icon = "fa fa-passport", listEntitlement = "")
-public class AuthProfile extends BaseExtPage {
+@AMPage(label = "Auth Profile", icon = "fa fa-passport", listEntitlement = "")
+public class AuthProfile extends BaseReauthPage {
 
     private static final long serialVersionUID = -3147262161518280928L;
 
@@ -56,14 +55,14 @@ public class AuthProfile extends BaseExtPage {
     public AuthProfile(final PageParameters parameters) {
         super(parameters, AUTH_PROFILE);
 
-        Optional<AuthProfileTO> authProfile = restClient.read();
+        AuthProfileTO authProfile = restClient.read();
 
         WebMarkupContainer container = new WebMarkupContainer("content");
         contentWrapper.add(container.setOutputMarkupId(true));
 
         DataView<ImpersonationAccount> impersonationAccounts = new DataView<>(
                 "impersonationAccounts", new ListDataProvider<>(
-                        authProfile.map(AuthProfileTO::getImpersonationAccounts).orElseGet(() -> List.of()))) {
+                        authProfile == null ? List.of() : authProfile.getImpersonationAccounts())) {
 
             private static final long serialVersionUID = 6127875313385810666L;
 
@@ -77,11 +76,11 @@ public class AuthProfile extends BaseExtPage {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
-                        authProfile.ifPresent(p -> {
-                            p.getImpersonationAccounts().remove(item.getModelObject());
-                            restClient.update(p);
+                        if (authProfile != null) {
+                            authProfile.getImpersonationAccounts().remove(item.getModelObject());
+                            restClient.update(authProfile);
                             target.add(container);
-                        });
+                        }
                     }
                 });
             }
@@ -92,7 +91,7 @@ public class AuthProfile extends BaseExtPage {
 
         DataView<GoogleMfaAuthToken> googleMfaAuthTokens = new DataView<>(
                 "googleMfaAuthTokens", new ListDataProvider<>(
-                        authProfile.map(AuthProfileTO::getGoogleMfaAuthTokens).orElseGet(() -> List.of()))) {
+                        authProfile == null ? List.of() : authProfile.getGoogleMfaAuthTokens())) {
 
             private static final long serialVersionUID = 6127875313385810666L;
 
@@ -107,11 +106,11 @@ public class AuthProfile extends BaseExtPage {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
-                        authProfile.ifPresent(p -> {
-                            p.getGoogleMfaAuthTokens().remove(item.getModelObject());
-                            restClient.update(p);
+                        if (authProfile != null) {
+                            authProfile.getGoogleMfaAuthTokens().remove(item.getModelObject());
+                            restClient.update(authProfile);
                             target.add(container);
-                        });
+                        }
                     }
                 });
             }
@@ -122,7 +121,7 @@ public class AuthProfile extends BaseExtPage {
 
         DataView<GoogleMfaAuthAccount> googleMfaAuthAccounts = new DataView<>(
                 "googleMfaAuthAccounts", new ListDataProvider<>(
-                        authProfile.map(AuthProfileTO::getGoogleMfaAuthAccounts).orElseGet(() -> List.of()))) {
+                        authProfile == null ? List.of() : authProfile.getGoogleMfaAuthAccounts())) {
 
             private static final long serialVersionUID = 6127875313385810666L;
 
@@ -143,11 +142,11 @@ public class AuthProfile extends BaseExtPage {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
-                        authProfile.ifPresent(p -> {
-                            p.getGoogleMfaAuthAccounts().remove(item.getModelObject());
-                            restClient.update(p);
+                        if (authProfile != null) {
+                            authProfile.getGoogleMfaAuthAccounts().remove(item.getModelObject());
+                            restClient.update(authProfile);
                             target.add(container);
-                        });
+                        }
                     }
                 });
             }
@@ -158,7 +157,7 @@ public class AuthProfile extends BaseExtPage {
 
         DataView<MfaTrustedDevice> mfaTrustedDevices = new DataView<>(
                 "mfaTrustedDevices", new ListDataProvider<>(
-                        authProfile.map(AuthProfileTO::getMfaTrustedDevices).orElseGet(() -> List.of()))) {
+                        authProfile == null ? List.of() : authProfile.getMfaTrustedDevices())) {
 
             private static final long serialVersionUID = 6127875313385810666L;
 
@@ -176,11 +175,11 @@ public class AuthProfile extends BaseExtPage {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
-                        authProfile.ifPresent(p -> {
-                            p.getMfaTrustedDevices().remove(item.getModelObject());
-                            restClient.update(p);
+                        if (authProfile != null) {
+                            authProfile.getMfaTrustedDevices().remove(item.getModelObject());
+                            restClient.update(authProfile);
                             target.add(container);
-                        });
+                        }
                     }
                 });
             }
@@ -191,7 +190,7 @@ public class AuthProfile extends BaseExtPage {
 
         DataView<WebAuthnDeviceCredential> webAuthnDeviceCredentials = new DataView<>(
                 "webAuthnDeviceCredentials", new ListDataProvider<>(
-                        authProfile.map(AuthProfileTO::getWebAuthnDeviceCredentials).orElseGet(() -> List.of()))) {
+                        authProfile == null ? List.of() : authProfile.getWebAuthnDeviceCredentials())) {
 
             private static final long serialVersionUID = 6127875313385810666L;
 
@@ -205,11 +204,11 @@ public class AuthProfile extends BaseExtPage {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
-                        authProfile.ifPresent(p -> {
-                            p.getWebAuthnDeviceCredentials().remove(item.getModelObject());
-                            restClient.update(p);
+                        if (authProfile != null) {
+                            authProfile.getWebAuthnDeviceCredentials().remove(item.getModelObject());
+                            restClient.update(authProfile);
                             target.add(container);
-                        });
+                        }
                     }
                 });
             }
diff --git a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java
index 413247746f..2714954ff5 100644
--- a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java
+++ b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.enduser.rest;
 
-import java.util.Optional;
 import org.apache.syncope.common.lib.to.AuthProfileTO;
 import org.apache.syncope.common.rest.api.service.AuthProfileSelfService;
 
@@ -26,12 +25,12 @@ public class AuthProfileRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = 4139153766778113329L;
 
-    public Optional<AuthProfileTO> read() {
+    public AuthProfileTO read() {
         try {
-            return Optional.of(getService(AuthProfileSelfService.class).read());
+            return getService(AuthProfileSelfService.class).read();
         } catch (Exception e) {
             LOG.debug("While attempting to read the auth profile", e);
-            return Optional.empty();
+            return null;
         }
     }
 
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
index 02ae460c80..58eae319b4 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
@@ -21,11 +21,11 @@ package org.apache.syncope.client.console.topology;
 import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.syncope.client.console.annotations.IdMPage;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.pages.Connectors;
 import org.apache.syncope.client.console.pages.Resources;
 import org.apache.syncope.client.console.panels.ConnidLocations;
+import org.apache.syncope.client.ui.commons.annotations.IdMPage;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
 import org.apache.wicket.extensions.markup.html.tabs.ITab;
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index d22d706d51..cbc218e1de 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -36,7 +36,6 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.annotations.IdMPage;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
@@ -46,6 +45,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.resources.AbstractResourceWizardBuilder.CreateEvent;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.annotations.IdMPage;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java
index f51e641a17..b00a81f4b4 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java
@@ -26,6 +26,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Locale;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel;
 import org.apache.syncope.client.ui.commons.panels.NotificationPanel;
 import org.apache.syncope.common.keymaster.client.api.DomainOps;
 import org.apache.syncope.common.keymaster.client.api.model.Domain;
@@ -45,7 +46,6 @@ import org.apache.wicket.markup.html.form.StatelessForm;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
@@ -73,6 +73,10 @@ public abstract class BaseLogin extends WebPage {
 
     protected final TextField<String> passwordField;
 
+    protected final LocaleDropDown languageSelect;
+
+    protected final DomainDropDown domainSelect;
+
     protected String notificationMessage;
 
     protected String notificationLevel;
@@ -97,7 +101,7 @@ public abstract class BaseLogin extends WebPage {
         notificationPanel = new NotificationPanel(Constants.FEEDBACK);
         add(notificationPanel);
 
-        if (!parameters.get("notificationMessage").isNull()) {
+        if (!parameters.get(Constants.NOTIFICATION_MSG_PARAM).isNull()) {
             notificationMessage = parameters.get(Constants.NOTIFICATION_MSG_PARAM).toString();
             notificationLevel = parameters.get(Constants.NOTIFICATION_LEVEL_PARAM).isEmpty()
                     ? Notification.SUCCESS
@@ -123,7 +127,7 @@ public abstract class BaseLogin extends WebPage {
         passwordField.setMarkupId("password");
         form.add(passwordField);
 
-        LocaleDropDown languageSelect = new LocaleDropDown("language");
+        languageSelect = new LocaleDropDown("language");
         languageSelect.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
 
             private static final long serialVersionUID = -1107858522700306810L;
@@ -143,7 +147,7 @@ public abstract class BaseLogin extends WebPage {
         });
         form.add(languageSelect.setOutputMarkupId(true));
 
-        DomainDropDown domainSelect = new DomainDropDown("domain", domains);
+        domainSelect = new DomainDropDown("domain", domains);
         domainSelect.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
 
             private static final long serialVersionUID = -1107858522700306810L;
@@ -169,21 +173,19 @@ public abstract class BaseLogin extends WebPage {
 
             @Override
             protected void onSubmit(final AjaxRequestTarget target) {
-                authenticate(usernameField.getRawInput(), passwordField.getRawInput(), target);
+                authenticate(usernameField.getValue(), passwordField.getRawInput(), target);
             }
-
         };
         submitButton.setDefaultFormProcessing(false);
         form.add(submitButton);
         form.setDefaultButton(submitButton);
 
-        List<Panel> ssoLoginFormPanels = getSSOLoginFormPanels();
-        ListView<Panel> ssoLogins = new ListView<>("ssoLogins", ssoLoginFormPanels) {
+        ListView<BaseSSOLoginFormPanel> ssoLogins = new ListView<>("ssoLogins", getSSOLoginFormPanels()) {
 
             private static final long serialVersionUID = -9180479401817023838L;
 
             @Override
-            protected void populateItem(final ListItem<Panel> item) {
+            protected void populateItem(final ListItem<BaseSSOLoginFormPanel> item) {
                 item.add(item.getModelObject());
             }
         };
@@ -203,16 +205,19 @@ public abstract class BaseLogin extends WebPage {
     @Override
     public void renderHead(final IHeaderResponse response) {
         super.renderHead(response);
+
         if (StringUtils.isNotBlank(notificationMessage)) {
-            response.render(OnLoadHeaderItem.forScript(StyledNotificationBehavior.jQueryShow(notificationMessage,
+            response.render(OnLoadHeaderItem.forScript(StyledNotificationBehavior.jQueryShow(
+                    notificationMessage,
                     String.format("jQuery('#%s').data('kendoNotification')",
-                            notificationPanel.getNotificationMarkupId()), notificationLevel)));
+                            notificationPanel.getNotificationMarkupId()),
+                    notificationLevel)));
         }
     }
 
     protected abstract BaseSession getBaseSession();
 
-    protected abstract List<Panel> getSSOLoginFormPanels();
+    protected abstract List<BaseSSOLoginFormPanel> getSSOLoginFormPanels();
 
     protected abstract void sendError(String error);
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/AMPage.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/AMPage.java
similarity index 96%
rename from client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/AMPage.java
rename to client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/AMPage.java
index 86a9c6d6b5..d4404c8483 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/AMPage.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/AMPage.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.client.console.annotations;
+package org.apache.syncope.client.ui.commons.annotations;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/IdMPage.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/IdMPage.java
similarity index 96%
rename from client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/IdMPage.java
rename to client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/IdMPage.java
index 6943636404..239f5cefd4 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/IdMPage.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/IdMPage.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.client.console.annotations;
+package org.apache.syncope.client.ui.commons.annotations;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java
index 9675eb7bab..4e9117387f 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java
@@ -24,7 +24,13 @@ public abstract class BaseSSOLoginFormPanel extends Panel {
 
     private static final long serialVersionUID = -2371733568360773586L;
 
+    protected boolean reauth;
+
     public BaseSSOLoginFormPanel(final String id) {
         super(id);
     }
+
+    public void setReauth(final boolean reauth) {
+        this.reauth = reauth;
+    }
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
index e8a5b94555..a7a04597f7 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
@@ -34,15 +34,15 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.client.console.ConsoleProperties;
-import org.apache.syncope.client.console.annotations.AMPage;
-import org.apache.syncope.client.console.annotations.IdMPage;
 import org.apache.syncope.client.console.pages.BaseExtPage;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.widgets.BaseExtWidget;
 import org.apache.syncope.client.console.widgets.ExtAlertWidget;
+import org.apache.syncope.client.ui.commons.annotations.AMPage;
 import org.apache.syncope.client.ui.commons.annotations.BinaryPreview;
 import org.apache.syncope.client.ui.commons.annotations.ExtPage;
 import org.apache.syncope.client.ui.commons.annotations.ExtWidget;
+import org.apache.syncope.client.ui.commons.annotations.IdMPage;
 import org.apache.syncope.client.ui.commons.markup.html.form.preview.BinaryPreviewer;
 import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel;
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index 8490ed6aea..6a1b8fe56b 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -26,14 +26,14 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.SyncopeWebApplication;
-import org.apache.syncope.client.console.annotations.AMPage;
-import org.apache.syncope.client.console.annotations.IdMPage;
 import org.apache.syncope.client.console.panels.DelegationSelectionPanel;
 import org.apache.syncope.client.console.rest.SyncopeRestClient;
 import org.apache.syncope.client.console.wicket.markup.head.MetaHeaderItem;
 import org.apache.syncope.client.console.widgets.ExtAlertWidget;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.annotations.AMPage;
 import org.apache.syncope.client.ui.commons.annotations.ExtPage;
+import org.apache.syncope.client.ui.commons.annotations.IdMPage;
 import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink;
 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
 import org.apache.syncope.common.lib.SyncopeConstants;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
index 4b923e1a31..07b33ad058 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
@@ -29,7 +29,6 @@ import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.authentication.IAuthenticationStrategy;
 import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
-import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class Login extends BaseLogin {
@@ -46,8 +45,8 @@ public class Login extends BaseLogin {
     }
 
     @Override
-    protected List<Panel> getSSOLoginFormPanels() {
-        List<Panel> ssoLoginFormPanels = new ArrayList<>();
+    protected List<BaseSSOLoginFormPanel> getSSOLoginFormPanels() {
+        List<BaseSSOLoginFormPanel> ssoLoginFormPanels = new ArrayList<>();
         SyncopeWebApplication.get().getLookup().getClasses(BaseSSOLoginFormPanel.class).forEach(ssoLoginFormPanel -> {
             try {
                 ssoLoginFormPanels.add(ssoLoginFormPanel.getConstructor(String.class, BaseSession.class).newInstance(
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java
index 7f5c806437..5272b5b0de 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.enduser;
 
+import java.util.Optional;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
 
@@ -34,9 +35,7 @@ public final class BookmarkablePageLinkBuilder {
 
         @SuppressWarnings("unchecked")
         Class<T> pageClass = (Class<T>) SyncopeWebApplication.get().getPageClass(key);
-        return new BookmarkablePageLink<>(
-                id,
-                pageClass == null ? defaultPageClass : pageClass);
+        return new BookmarkablePageLink<>(id, Optional.ofNullable(pageClass).orElse(defaultPageClass));
     }
 
     private BookmarkablePageLinkBuilder() {
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java
index 93a46de7ae..ee73825248 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java
@@ -36,6 +36,8 @@ public class EnduserProperties extends CommonUIProperties {
 
     private boolean captcha;
 
+    private Long reauthExpirationMinutesTimeout;
+
     private boolean reportPropagationErrors;
 
     private boolean reportPropagationErrorDetails;
@@ -66,6 +68,14 @@ public class EnduserProperties extends CommonUIProperties {
         this.captcha = captcha;
     }
 
+    public Long getReauthExpirationMinutesTimeout() {
+        return reauthExpirationMinutesTimeout;
+    }
+
+    public void setReauthExpirationMinutesTimeout(final Long reauthExpirationMinutesTimeout) {
+        this.reauthExpirationMinutesTimeout = reauthExpirationMinutesTimeout;
+    }
+
     public boolean isReportPropagationErrors() {
         return reportPropagationErrors;
     }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
index 8f4c78fd2d..044b3473e6 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
@@ -25,6 +25,8 @@ import jakarta.ws.rs.core.EntityTag;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.xml.ws.WebServiceException;
 import java.text.DateFormat;
+import java.time.OffsetDateTime;
+import java.time.temporal.ChronoUnit;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -102,12 +104,30 @@ public class SyncopeEnduserSession extends AuthenticatedWebSession implements Ba
 
     protected UserTO selfTO;
 
+    protected OffsetDateTime lastReauth;
+
     public SyncopeEnduserSession(final Request request) {
         super(request);
 
         clientFactory = SyncopeWebApplication.get().newClientFactory();
     }
 
+    public boolean isReauthExpired() {
+        return SyncopeWebApplication.get().getReauthExpirationMinutesTimeout().
+                map(timeout -> Optional.ofNullable(lastReauth).
+                map(r -> ChronoUnit.MINUTES.between(r, OffsetDateTime.now()) > timeout).
+                orElse(true)).
+                orElse(false);
+    }
+
+    public void setLastReauth() {
+        this.lastReauth = OffsetDateTime.now();
+    }
+
+    public void clearLastReauth() {
+        this.lastReauth = null;
+    }
+
     protected String message(final SyncopeClientException sce) {
         Error error = null;
         if (sce.getType() == ClientExceptionType.InvalidSecurityAnswer) {
@@ -179,7 +199,7 @@ public class SyncopeEnduserSession extends AuthenticatedWebSession implements Ba
 
     @Override
     public String getJWT() {
-        return client == null ? null : client.getJWT();
+        return Optional.ofNullable(client).map(SyncopeClient::getJWT).orElse(null);
     }
 
     @Override
@@ -246,11 +266,11 @@ public class SyncopeEnduserSession extends AuthenticatedWebSession implements Ba
     }
 
     protected boolean isAuthenticated() {
-        return client != null && client.getJWT() != null;
+        return getJWT() != null;
     }
 
     protected boolean isMustChangePassword() {
-        return selfTO != null && selfTO.isMustChangePassword();
+        return Optional.ofNullable(selfTO).map(UserTO::isMustChangePassword).orElse(false);
     }
 
     public void cleanup() {
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
index c0ce8f1393..52a5b894de 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
@@ -28,6 +28,7 @@ import de.agilecoders.wicket.core.settings.SingleThemeProvider;
 import java.io.InputStream;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
 import org.apache.syncope.client.enduser.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.enduser.pages.BasePage;
@@ -301,6 +302,10 @@ public class SyncopeWebApplication extends WicketBootSecuredWebApplication {
         return props.isCaptcha();
     }
 
+    public Optional<Long> getReauthExpirationMinutesTimeout() {
+        return Optional.ofNullable(props.getReauthExpirationMinutesTimeout());
+    }
+
     public boolean isReportPropagationErrors() {
         return props.isReportPropagationErrors();
     }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java
index 07719f91b4..cdc5d35332 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java
@@ -21,18 +21,12 @@ package org.apache.syncope.client.enduser.commons;
 public final class EnduserConstants {
 
     public static final String STATUS = "status";
-    
-    public static final String SUCCESS = "success";
-    
-    public static final String FAILING_RESOURCES = "failing_resources";
 
     public static final String LANDING_PAGE = "landingPage";
 
     public static final String CONTENT_PANEL = "contentPanel";
 
-    public static final String SELF_ALLOWED = "selfRegistration.allowed";
-
-    public static final String PAGE_TITLE = "pageTitle";
+    public static final String REAUTH = "reauth";
 
     private EnduserConstants() {
         // private constructor for static utility class
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java
index 042df772fc..d5c4d2b34b 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java
@@ -22,13 +22,16 @@ import java.io.Serializable;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Objects;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.client.enduser.pages.BaseExtPage;
 import org.apache.syncope.client.enduser.pages.BasePage;
+import org.apache.syncope.client.ui.commons.annotations.AMPage;
 import org.apache.syncope.client.ui.commons.annotations.BinaryPreview;
 import org.apache.syncope.client.ui.commons.annotations.ExtPage;
+import org.apache.syncope.client.ui.commons.annotations.IdMPage;
 import org.apache.syncope.client.ui.commons.markup.html.form.preview.BinaryPreviewer;
 import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel;
 import org.slf4j.Logger;
@@ -48,6 +51,10 @@ public class ClassPathScanImplementationLookup implements Serializable {
 
     private List<Class<? extends BaseSSOLoginFormPanel>> ssoLoginFormPanels;
 
+    private List<Class<? extends BasePage>> idmPages;
+
+    private List<Class<? extends BasePage>> amPages;
+
     private List<Class<? extends BasePage>> extPages;
 
     private List<Class<? extends BinaryPreviewer>> previewers;
@@ -63,6 +70,8 @@ public class ClassPathScanImplementationLookup implements Serializable {
 
     @SuppressWarnings("unchecked")
     public void load() {
+        idmPages = new ArrayList<>();
+        amPages = new ArrayList<>();
         extPages = new ArrayList<>();
         ssoLoginFormPanels = new ArrayList<>();
         previewers = new ArrayList<>();
@@ -87,6 +96,12 @@ public class ClassPathScanImplementationLookup implements Serializable {
                         LOG.error("Could not find annotation {} in {}, ignoring",
                                 ExtPage.class.getName(), clazz.getName());
                     }
+                } else if (BasePage.class.isAssignableFrom(clazz)) {
+                    if (clazz.isAnnotationPresent(IdMPage.class)) {
+                        idmPages.add((Class<? extends BasePage>) clazz);
+                    } else if (clazz.isAnnotationPresent(AMPage.class)) {
+                        amPages.add((Class<? extends BasePage>) clazz);
+                    }
                 } else if (BaseSSOLoginFormPanel.class.isAssignableFrom(clazz)) {
                     ssoLoginFormPanels.add((Class<? extends BaseSSOLoginFormPanel>) clazz);
                 } else if (BinaryPreviewer.class.isAssignableFrom(clazz)) {
@@ -97,13 +112,29 @@ public class ClassPathScanImplementationLookup implements Serializable {
             }
         }
 
+        idmPages.sort(Comparator.comparing(o -> o.getAnnotation(IdMPage.class).priority()));
+        idmPages = Collections.unmodifiableList(idmPages);
+
+        amPages.sort(Comparator.comparing(o -> o.getAnnotation(AMPage.class).priority()));
+        amPages = Collections.unmodifiableList(amPages);
+
         ssoLoginFormPanels = Collections.unmodifiableList(ssoLoginFormPanels);
 
+        LOG.debug("IdM pages found: {}", idmPages);
+        LOG.debug("AM pages found: {}", amPages);
         LOG.debug("Extension pages found: {}", extPages);
         LOG.debug("SSO Login pages found: {}", ssoLoginFormPanels);
         LOG.debug("Binary previewers found: {}", previewers);
     }
 
+    public List<Class<? extends BasePage>> getIdMPageClasses() {
+        return idmPages;
+    }
+
+    public List<Class<? extends BasePage>> getAMPageClasses() {
+        return amPages;
+    }
+
     public List<Class<? extends BaseSSOLoginFormPanel>> getSSOLoginFormPanels() {
         return this.ssoLoginFormPanels;
     }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java
index f9840a83f0..4d23492d9c 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java
@@ -65,5 +65,4 @@ public class SidebarLayout implements Serializable {
     public boolean isExtensionEnabled(final String key) {
         return extensionsEnabled.getOrDefault(key, true);
     }
-
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java
index c350a1689b..3a7d9c0eea 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java
@@ -29,13 +29,13 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
-public abstract class AbstractChangePassword extends BasePage {
+abstract class AbstractChangePassword extends BaseReauthPage {
 
     private static final long serialVersionUID = 5889157642852559004L;
 
     private static final String CHANGE_PASSWORD = "page.changePassword";
 
-    public AbstractChangePassword(final PageParameters parameters) {
+    protected AbstractChangePassword(final PageParameters parameters) {
         super(parameters, CHANGE_PASSWORD);
 
         WebMarkupContainer content = new WebMarkupContainer("content");
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java
index 30238672cd..7a477848c1 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java
@@ -24,10 +24,6 @@ public abstract class BaseExtPage extends BasePage {
 
     private static final long serialVersionUID = 4627828052717627159L;
 
-    public BaseExtPage() {
-        super();
-    }
-
     public BaseExtPage(final PageParameters parameters, final String name) {
         super(parameters, name);
     }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java
index a0d13ea43a..93197b6f42 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java
@@ -19,11 +19,8 @@
 package org.apache.syncope.client.enduser.pages;
 
 import java.io.Serializable;
-import java.util.List;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.SyncopeWebApplication;
-import org.apache.syncope.client.enduser.commons.EnduserConstants;
-import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
 import org.apache.syncope.client.enduser.panels.Sidebar;
 import org.apache.syncope.client.enduser.wicket.markup.head.MetaHeaderItem;
 import org.apache.syncope.client.ui.commons.BaseSession;
@@ -47,17 +44,13 @@ import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.wicket.spring.injection.annot.SpringBean;
 
-public class BasePage extends BaseWebPage {
+public abstract class BasePage extends BaseWebPage {
 
     private static final long serialVersionUID = 1571997737305598502L;
 
     protected static final HeaderItem META_IE_EDGE = new MetaHeaderItem("X-UA-Compatible", "IE=edge");
 
-    @SpringBean
-    private ClassPathScanImplementationLookup lookup;
-
     protected final Sidebar sidebar;
 
     protected final WebMarkupContainer contentWrapper;
@@ -66,10 +59,6 @@ public class BasePage extends BaseWebPage {
 
     protected final AjaxLink<Void> collapse;
 
-    public BasePage() {
-        this(null, null);
-    }
-
     public BasePage(final PageParameters parameters, final String name) {
         super(parameters);
 
@@ -80,17 +69,12 @@ public class BasePage extends BaseWebPage {
 
         // sidebar
         Class<? extends Sidebar> clazz = SyncopeWebApplication.get().getSidebar();
-
         try {
-            sidebar = clazz.getConstructor(
-                    String.class,
-                    PageReference.class,
-                    List.class).
-                    newInstance("sidebar", getPageReference(), lookup.getExtPageClasses());
+            sidebar = clazz.getConstructor(String.class, PageReference.class).
+                    newInstance("sidebar", getPageReference());
         } catch (Exception e) {
             throw new IllegalArgumentException("Could not instantiate " + clazz.getName(), e);
         }
-
         sidebar.setOutputMarkupPlaceholderTag(true);
         body.add(sidebar);
 
@@ -157,7 +141,7 @@ public class BasePage extends BaseWebPage {
     }
 
     protected void addPageTitle(final String title) {
-        contentWrapper.addOrReplace(new Label(EnduserConstants.PAGE_TITLE, new ResourceModel(title, title)));
+        contentWrapper.addOrReplace(new Label("pageTitle", new ResourceModel(title, title)));
     }
 
     protected void disableSidebarAndNavbar() {
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseReauthPage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseReauthPage.java
new file mode 100644
index 0000000000..8bc66fd30a
--- /dev/null
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseReauthPage.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.pages;
+
+import com.googlecode.wicket.kendo.ui.widget.notification.Notification;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.wicket.RestartResponseAtInterceptPageException;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+abstract class BaseReauthPage extends BasePage {
+
+    private static final long serialVersionUID = 417902520012512819L;
+
+    protected BaseReauthPage(final PageParameters parameters, final String name) {
+        super(parameters, name);
+
+        if (isReauthExpired()) {
+            LOG.debug("Re-authentication needed to proceed");
+
+            PageParameters notification = new PageParameters();
+            notification.add(Constants.NOTIFICATION_MSG_PARAM, getString("reauth.message"));
+            notification.add(Constants.NOTIFICATION_LEVEL_PARAM, Notification.WARNING);
+
+            throw new RestartResponseAtInterceptPageException(ReauthLogin.class, notification);
+        } else {
+            SyncopeEnduserSession.get().clearLastReauth();
+            LOG.debug("Re-authentication cleared");
+        }
+    }
+
+    protected boolean isReauthExpired() {
+        return SyncopeEnduserSession.get().isReauthExpired();
+    }
+}
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java
index be6053bdd8..85db92c7f7 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java
@@ -48,17 +48,18 @@ public class EditChangePassword extends AbstractChangePassword {
         try {
             UserTO userTO = getPwdLoggedUser();
             // update and set page paramters according to provisioning result
-            ProvisioningResult<UserTO> provisioningResult =
-                    userSelfRestClient.update(
-                            userTO.getETagValue(),
-                            new UserUR.Builder(userTO.getKey()).
-                                    password(new PasswordPatch.Builder().
-                                            value(passwordField.getModelObject()).onSyncope(true).
-                                            resources(userTO.getResources()).
-                                            build()).
-                                    build());
+            ProvisioningResult<UserTO> provisioningResult = userSelfRestClient.update(
+                    userTO.getETagValue(),
+                    new UserUR.Builder(userTO.getKey()).
+                            password(new PasswordPatch.Builder().
+                                    value(passwordField.getModelObject()).onSyncope(true).
+                                    resources(userTO.getResources()).
+                                    build()).
+                            build());
             setResponsePage(new SelfResult(provisioningResult,
-                    ProvisioningUtils.managePageParams(EditChangePassword.this, "pwd.change",
+                    ProvisioningUtils.managePageParams(
+                            EditChangePassword.this,
+                            "pwd.change",
                             !SyncopeWebApplication.get().isReportPropagationErrors()
                             || provisioningResult.getPropagationStatuses().stream().
                                     allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus()))));
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java
index 065babe8fb..f766ce679a 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java
@@ -52,7 +52,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
-public class EditSecurityQuestion extends BasePage {
+public class EditSecurityQuestion extends BaseReauthPage {
 
     private static final long serialVersionUID = -537205681762708502L;
 
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java
index c890664ef1..f0da515338 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java
@@ -27,7 +27,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
-public class EditUser extends BasePage {
+public class EditUser extends BaseReauthPage {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java
index 776faabc63..e956d28d32 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java
@@ -28,19 +28,19 @@ import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.SyncopeWebApplication;
 import org.apache.syncope.client.ui.commons.BaseLogin;
 import org.apache.syncope.client.ui.commons.BaseSession;
+import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
-import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 public class Login extends BaseLogin {
 
     private static final long serialVersionUID = 5889157642852559004L;
 
-    private final BookmarkablePageLink<Void> selfPwdReset;
+    protected final BookmarkablePageLink<Void> selfPwdReset;
 
-    private final BookmarkablePageLink<Void> selfRegistration;
+    protected final BookmarkablePageLink<Void> selfRegistration;
 
     public Login(final PageParameters parameters) {
         super(parameters);
@@ -70,8 +70,8 @@ public class Login extends BaseLogin {
     }
 
     @Override
-    protected List<Panel> getSSOLoginFormPanels() {
-        List<Panel> ssoLoginFormPanels = new ArrayList<>();
+    protected List<BaseSSOLoginFormPanel> getSSOLoginFormPanels() {
+        List<BaseSSOLoginFormPanel> ssoLoginFormPanels = new ArrayList<>();
         SyncopeWebApplication.get().getLookup().getSSOLoginFormPanels().forEach(ssoLoginFormPanel -> {
             try {
                 ssoLoginFormPanels.add(ssoLoginFormPanel.getConstructor(String.class, BaseSession.class).newInstance(
@@ -88,6 +88,18 @@ public class Login extends BaseLogin {
         SyncopeEnduserSession.get().error(error);
     }
 
+    protected void onAuthenticateSuccess(final AjaxRequestTarget target) {
+        // If login has been called because the user was not yet logged in, than continue to the
+        // original destination, otherwise to the Home page
+        continueToOriginalDestination();
+        setResponsePage(getApplication().getHomePage());
+    }
+
+    protected void onAuthenticateFailure(final AjaxRequestTarget target) {
+        SyncopeEnduserSession.get().error(getString("login-error"));
+        notificationPanel.refresh(target);
+    }
+
     @Override
     protected void authenticate(final String username, final String password, final AjaxRequestTarget target)
             throws NotAuthorizedException {
@@ -99,13 +111,9 @@ public class Login extends BaseLogin {
         }
 
         if (SyncopeEnduserSession.get().authenticate(username, password)) {
-            // If login has been called because the user was not yet logged in, than continue to the
-            // original destination, otherwise to the Home page
-            continueToOriginalDestination();
-            setResponsePage(getApplication().getHomePage());
+            onAuthenticateSuccess(target);
         } else {
-            SyncopeEnduserSession.get().error(getString("login-error"));
-            notificationPanel.refresh(target);
+            onAuthenticateFailure(target);
         }
     }
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java
index 48318cd421..7be2655617 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java
@@ -43,6 +43,11 @@ public class MustChangePassword extends AbstractChangePassword {
         disableSidebarAndNavbar();
     }
 
+    @Override
+    protected boolean isReauthExpired() {
+        return false;
+    }
+
     @Override
     protected void doPwdSubmit(final AjaxRequestTarget target, final AjaxPasswordFieldPanel passwordField) {
         try {
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/ReauthLogin.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/ReauthLogin.java
new file mode 100644
index 0000000000..ec5da8fc7c
--- /dev/null
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/ReauthLogin.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.pages;
+
+import java.util.List;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+public class ReauthLogin extends Login {
+
+    private static final long serialVersionUID = -218346357365913190L;
+
+    public ReauthLogin(final PageParameters parameters) {
+        super(parameters);
+
+        SyncopeEnduserSession session = SyncopeEnduserSession.get();
+
+        usernameField.setEnabled(false);
+        usernameField.setModelObject(session.getSelfTO().getUsername());
+        usernameField.modelChanged();
+
+        languageSelect.setEnabled(false);
+        languageSelect.setModelObject(session.getLocale());
+        languageSelect.modelChanged();
+
+        domainSelect.setEnabled(false);
+        domainSelect.setModelObject(session.getDomain());
+        domainSelect.modelChanged();
+
+        selfPwdReset.setVisible(false);
+        selfRegistration.setVisible(false);
+    }
+
+    @Override
+    protected List<BaseSSOLoginFormPanel> getSSOLoginFormPanels() {
+        List<BaseSSOLoginFormPanel> panels = super.getSSOLoginFormPanels();
+        panels.forEach(panel -> panel.setReauth(true));
+        return panels;
+    }
+
+    @Override
+    protected void onAuthenticateSuccess(final AjaxRequestTarget target) {
+        SyncopeEnduserSession.get().setLastReauth();
+        super.onAuthenticateSuccess(target);
+    }
+}
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java
index 06f9dc306f..d0dc14ec93 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.client.enduser.panels;
 
 import java.util.List;
-import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.BookmarkablePageLinkBuilder;
@@ -31,7 +30,9 @@ import org.apache.syncope.client.enduser.pages.Dashboard;
 import org.apache.syncope.client.enduser.pages.EditChangePassword;
 import org.apache.syncope.client.enduser.pages.EditSecurityQuestion;
 import org.apache.syncope.client.enduser.pages.EditUser;
+import org.apache.syncope.client.ui.commons.annotations.AMPage;
 import org.apache.syncope.client.ui.commons.annotations.ExtPage;
+import org.apache.syncope.client.ui.commons.annotations.IdMPage;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
@@ -66,11 +67,7 @@ public class Sidebar extends Panel {
 
     protected WebMarkupContainer profileLIContainer;
 
-    public Sidebar(
-            final String id,
-            final PageReference pageRef,
-            final List<Class<? extends BasePage>> extPageClasses) {
-
+    public Sidebar(final String id, final PageReference pageRef) {
         super(id);
 
         buildBaseSidebar();
@@ -130,10 +127,83 @@ public class Sidebar extends Panel {
             }
         }
 
+        List<Class<? extends BasePage>> idmPageClasses = SyncopeWebApplication.get().getLookup().getIdMPageClasses();
+        ListView<Class<? extends BasePage>> idmPages = new ListView<>("idmPages", idmPageClasses) {
+
+            private static final long serialVersionUID = 4949588177564901031L;
+
+            @Override
+            protected void populateItem(final ListItem<Class<? extends BasePage>> item) {
+                WebMarkupContainer containingLI = new WebMarkupContainer("idmPageLI");
+                item.add(containingLI);
+
+                IdMPage ann = item.getModelObject().getAnnotation(IdMPage.class);
+
+                BookmarkablePageLink<Page> link = new BookmarkablePageLink<>("idmPage", item.getModelObject());
+
+                link.add(new Label("idmPageLabel", ann.label()));
+
+                if (item.getModelObject().equals(pageRef.getPage().getClass())) {
+                    link.add(new Behavior() {
+
+                        private static final long serialVersionUID = 1469628524240283489L;
+
+                        @Override
+                        public void onComponentTag(final Component component, final ComponentTag tag) {
+                            tag.append("class", "active", " ");
+                        }
+                    });
+                }
+                containingLI.add(link);
+
+                Label idmPageIcon = new Label("idmPageIcon");
+                idmPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon()));
+                link.add(idmPageIcon);
+            }
+        };
+        add(idmPages.setRenderBodyOnly(true).setOutputMarkupId(true));
+
+        List<Class<? extends BasePage>> amPageClasses = SyncopeWebApplication.get().getLookup().getAMPageClasses();
+        ListView<Class<? extends BasePage>> amPages = new ListView<>("amPages", amPageClasses) {
+
+            private static final long serialVersionUID = 4949588177564901031L;
+
+            @Override
+            protected void populateItem(final ListItem<Class<? extends BasePage>> item) {
+                WebMarkupContainer containingLI = new WebMarkupContainer("amPageLI");
+                item.add(containingLI);
+
+                AMPage ann = item.getModelObject().getAnnotation(AMPage.class);
+
+                BookmarkablePageLink<Page> link = new BookmarkablePageLink<>("amPage", item.getModelObject());
+
+                link.add(new Label("amPageLabel", ann.label()));
+
+                if (item.getModelObject().equals(pageRef.getPage().getClass())) {
+                    link.add(new Behavior() {
+
+                        private static final long serialVersionUID = 1469628524240283489L;
+
+                        @Override
+                        public void onComponentTag(final Component component, final ComponentTag tag) {
+                            tag.append("class", "active", " ");
+                        }
+                    });
+                }
+                containingLI.add(link);
+
+                Label amPageIcon = new Label("amPageIcon");
+                amPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon()));
+                link.add(amPageIcon);
+            }
+        };
+        add(amPages.setRenderBodyOnly(true).setOutputMarkupId(true));
+
+        List<Class<? extends BasePage>> extPageClasses = SyncopeWebApplication.get().getLookup().getExtPageClasses();
         ListView<Class<? extends BasePage>> extPages = new ListView<>("extPages", extPageClasses.stream().
                 filter(epc -> SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout().
                 isExtensionEnabled(StringUtils.remove(epc.getAnnotation(ExtPage.class).label(), StringUtils.SPACE))).
-                collect(Collectors.toList())) {
+                toList()) {
 
             private static final long serialVersionUID = 4949588177564901031L;
 
@@ -172,7 +242,6 @@ public class Sidebar extends Panel {
                 link.add(extPageIcon);
             }
         };
-
         add(extPages.setRenderBodyOnly(true).setOutputMarkupId(true));
     }
 
@@ -195,12 +264,11 @@ public class Sidebar extends Panel {
 
         WebMarkupContainer liContainer = new WebMarkupContainer(getLIContainerId("edituser"));
         profileULContainer.add(liContainer);
-
         liContainer.add(BookmarkablePageLinkBuilder.build("edituser", EditUser.class)).
                 setVisible(layout.isEditUserEnabled());
+
         liContainer = new WebMarkupContainer(getLIContainerId("editchangepassword"));
         profileULContainer.add(liContainer);
-
         liContainer.add(BookmarkablePageLinkBuilder.build("editchangepassword", EditChangePassword.class)).
                 setVisible(layout.isPasswordManagementEnabled());
 
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java
index 46d589638b..c2db2294cb 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java
@@ -111,8 +111,11 @@ public class UserFormPanel extends AnyFormPanel implements UserForm {
                 ProvisioningResult<UserTO> provisioningResult = updateReq.isEmpty()
                         ? new ProvisioningResult<>()
                         : userSelfRestClient.update(getOriginalItem().getInnerObject().getETagValue(), updateReq);
-                setResponsePage(new SelfResult(provisioningResult,
-                        ProvisioningUtils.managePageParams(UserFormPanel.this, "profile.change",
+                setResponsePage(new SelfResult(
+                        provisioningResult,
+                        ProvisioningUtils.managePageParams(
+                                UserFormPanel.this,
+                                "profile.change",
                                 !SyncopeWebApplication.get().isReportPropagationErrors()
                                 || provisioningResult.getPropagationStatuses().stream()
                                         .allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus()))));
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java
index 18dbfe05a5..2ca11d8dc6 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.client.enduser.rest;
 
 import java.util.List;
-import org.apache.syncope.common.lib.to.TypeExtensionTO;
 import org.apache.syncope.common.rest.api.service.SyncopeService;
 
 public class SyncopeRestClient extends BaseRestClient {
@@ -27,13 +26,11 @@ public class SyncopeRestClient extends BaseRestClient {
     private static final long serialVersionUID = -2211371717449597247L;
 
     public List<String> searchUserTypeExtensions(final String groupName) {
-        List<String> types = List.of();
         try {
-            TypeExtensionTO typeExtensionTO = getService(SyncopeService.class).readUserTypeExtension(groupName);
-            types = typeExtensionTO == null ? types : typeExtensionTO.getAuxClasses();
+            return getService(SyncopeService.class).readUserTypeExtension(groupName).getAuxClasses();
         } catch (Exception e) {
-            LOG.error("While reading all any type classes for group [{}]", groupName, e);
+            LOG.debug("While reading any type classes for type extension of group {}", groupName, e);
+            return List.of();
         }
-        return types;
     }
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java
index 9f52674d14..9a4fd7dfee 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java
@@ -47,10 +47,6 @@ public class UserProfileWidget extends BaseWidget {
     }
 
     protected void addBaseFields(final WebMarkupContainer userProfile) {
-        Label username = new Label("username", userTO.getUsername());
-        username.setOutputMarkupId(true);
-        userProfile.add(username);
-
         Label changePwdDate = new Label("changePwdDate", userTO.getChangePwdDate());
         changePwdDate.setOutputMarkupId(true);
         userProfile.add(changePwdDate);
diff --git a/client/idrepo/enduser/src/main/resources/enduser.properties b/client/idrepo/enduser/src/main/resources/enduser.properties
index dbb723008c..eb30724e80 100644
--- a/client/idrepo/enduser/src/main/resources/enduser.properties
+++ b/client/idrepo/enduser/src/main/resources/enduser.properties
@@ -50,6 +50,7 @@ enduser.maxUploadFileSizeMB=5
 
 enduser.x-forward=true
 enduser.captcha=true
+enduser.reauth-expiration-minutes-timeout=1
 enduser.reportPropagationErrors=true
 enduser.reportPropagationErrorDetails=true
 enduser.csrf=true
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties
index 73f7b76e6b..160f91c717 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties
@@ -85,7 +85,7 @@ tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes
 home=Home
 profile=Personal Information
 requests=User Requests
-edituser=Edit profile
+edituser=Profile
 submit=Submit
 cancel=Cancel
 editchangepassword=Change password
@@ -98,7 +98,7 @@ user_request_error=Error during user request. Please contact your administrator
 page.home=Home
 page.changePassword=Change Password
 page.editSecurityQuestion=Edit Security Question
-page.edituser=Edit User
+page.edituser=Profile
 page.confirmPasswordReset=Confirm Password Reset
 page.selfPwdReset=Password Reset
 page.selfRegistration=Registration
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties
index 56d614e715..b7b5740c7a 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties
@@ -84,7 +84,7 @@ tooLargeFile=Le fichier est trop grand, la taille du fichier de t\u00e9l\u00e9ch
 home=Aper\u00e7u
 profile=Information personnelle
 requests=Demandes des utilisateurs
-edituser=Editer le profil
+edituser=Profil
 submit=Soumettre
 cancel=Annuler
 editchangepassword=Changer mot de passe
@@ -97,7 +97,7 @@ user_request_error=Erreur lors de la demande de l'utilisateur. Veuillez contacte
 page.home=Aper\u00e7u
 page.changePassword=Changer mot de passe
 page.editSecurityQuestion=Modifier la question de s\u00e9curit\u00e9
-page.edituser=Modifier l'utilisateur
+page.edituser=Profil
 page.confirmPasswordReset=Confirm Password Reset
 page.selfPwdReset=Password Reset
 page.selfRegistration=Enregistrement
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties
index dd04807630..dc325d6f8c 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties
@@ -81,16 +81,16 @@ invalid.security.answer=Risposta di sicurezza non valida
 tooLargeFile=File troppo grande, la dimensione massima ammessa \\u00e8 ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
 home=Home
 profile=Informazioni personali
-requests=User Requests
-edituser=Modifica profilo
-submit=Submit
-cancel=Cancel
+requests=Richieste utente
+edituser=Profilo
+submit=Invia
+cancel=Annulla
 editchangepassword=Gestione password
-attributes.derived=Derived Attributes
-attributes.plain=Plain Attributes
+attributes.derived=Attributi Derivati
+attributes.plain=Attributi
 captcha=Captcha
-details=Details
-user-requests-link=User Requests
+details=Dettagli
+user-requests-link=Richieste utente
 self-pwd-reset-link=Self Password Reset
 self-registration-link=Self Registration
 user_request_error=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema.
@@ -98,7 +98,7 @@ user_request_error=Errore durante la richiesta. Si prega di contattare l'amminis
 page.home=Home
 page.changePassword=Cambio Password
 page.editSecurityQuestion=Modifica domanda segreta
-page.edituser=Modifica profilo
+page.edituser=Profilo
 page.confirmPasswordReset=Conferma Reset Password
 page.selfPwdReset=Password Reset
 page.selfRegistration=Self Registration
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties
index 4b9640769e..4b48338b43 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties
@@ -80,7 +80,7 @@ tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes
 home=Home
 profile=Personal Information
 requests=User Requests
-edituser=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u7de8\u96c6
+edituser=Profile
 submit=Submit
 cancel=Cancel
 editchangepassword=Change password
@@ -96,7 +96,7 @@ user_request_error=\u30e6\u30fc\u30b6\u30fc\u30ea\u30af\u30a8\u30b9\u30c8\u4e2d\
 page.home=Home
 page.changePassword=Change Password
 page.editSecurityQuestion=Edit Security Question
-page.edituser=Edit User
+page.edituser=Profile
 page.confirmPasswordReset=Confirm Password Reset
 page.selfPwdReset=Password Reset
 page.selfRegistration=Registration
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties
index 45fc6c0abe..cd54499171 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties
@@ -98,7 +98,7 @@ user_request_error=Erro durante a solicita\u00e7\u00e3o do usu\u00e1rio. Por fav
 page.home=Home
 page.changePassword=Change Password
 page.editSecurityQuestion=Edit Security Question
-page.edituser=Edit User
+page.edituser=Profile
 page.confirmPasswordReset=Confirm Password Reset
 page.selfPwdReset=Password Reset
 page.selfRegistration=Registration
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties
index 4e79d544b0..5f0346504c 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties
@@ -81,7 +81,7 @@ tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes
 home=Home
 profile=Personal Information
 requests=User Requests
-edituser=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c
+edituser=Profile
 submit=Submit
 cancel=Cancel
 editchangepassword=Change password
@@ -97,7 +97,7 @@ user_request_error=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043
 page.home=Home
 page.changePassword=Change Password
 page.editSecurityQuestion=Edit Security Question
-page.edituser=Edit User
+page.edituser=Profile
 page.confirmPasswordReset=Confirm Password Reset
 page.selfPwdReset=Password Reset
 page.selfRegistration=Registration
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage.properties
similarity index 84%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage.properties
index 633e2c5033..1754bfabae 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage.properties
@@ -14,10 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-overview=Overview
-control=Control
-accessTokens=Access Tokens
-palette.available=Available
-palette.selected=Selected
-submit=Change
-cancel=Cancel
+reauth.message=Please authenticate again to proceed
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_fr.properties
similarity index 84%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_fr.properties
index 633e2c5033..1754bfabae 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_fr.properties
@@ -14,10 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-overview=Overview
-control=Control
-accessTokens=Access Tokens
-palette.available=Available
-palette.selected=Selected
-submit=Change
-cancel=Cancel
+reauth.message=Please authenticate again to proceed
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_it.properties
similarity index 84%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_it.properties
index 633e2c5033..ef988d7b2d 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_it.properties
@@ -14,10 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-overview=Overview
-control=Control
-accessTokens=Access Tokens
-palette.available=Available
-palette.selected=Selected
-submit=Change
-cancel=Cancel
+reauth.message=Si prega di autenticarsi per procedere
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ja.properties
similarity index 84%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ja.properties
index 633e2c5033..1754bfabae 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ja.properties
@@ -14,10 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-overview=Overview
-control=Control
-accessTokens=Access Tokens
-palette.available=Available
-palette.selected=Selected
-submit=Change
-cancel=Cancel
+reauth.message=Please authenticate again to proceed
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_pt_BR.properties
similarity index 84%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_pt_BR.properties
index 633e2c5033..1754bfabae 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_pt_BR.properties
@@ -14,10 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-overview=Overview
-control=Control
-accessTokens=Access Tokens
-palette.available=Available
-palette.selected=Selected
-submit=Change
-cancel=Cancel
+reauth.message=Please authenticate again to proceed
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ru.properties
similarity index 84%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ru.properties
index 633e2c5033..1754bfabae 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ru.properties
@@ -14,10 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-overview=Overview
-control=Control
-accessTokens=Access Tokens
-palette.available=Available
-palette.selected=Selected
-submit=Change
-cancel=Cancel
+reauth.message=Please authenticate again to proceed
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties
index 451aab8071..8149cbc7b3 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties
@@ -15,8 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 password=Password
-submit=Change
-cancel=Cancel
 confirmPassword=Password (confirm)
 passwordNeedsToBeUpdated=Password needs to be updated
 self.pwd.change.success.msg=Password successfully changed
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties
index eb20e467e1..ba9c4c8c5c 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties
@@ -14,8 +14,6 @@
 #  limitations under the License.
 #
 password=Mot de passe
-submit=Modifier
-cancel=Annuler
 confirmPassword=Confirmer le mot de passe
 passwordNeedsToBeUpdated=Le mot de passe doit \u00eatre mis \u00e0 jour
 self.pwd.change.success.msg=Mot de passe chang\u00e9 avec succ\u00e8s
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties
index 0b6cc61778..e95f5f65f4 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties
@@ -15,8 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 password=Password
-submit=Cambia
-cancel=Annulla
 confirmPassword=Password (conferma)
 passwordNeedsToBeUpdated=La password deve essere aggiornata
 self.pwd.change.success.msg=Password aggiornata con successo
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties
index 9361a16669..ca3081b38b 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties
@@ -15,8 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 password=\u30d1\u30b9\u30ef\u30fc\u30c9
-submit=\u5909\u66f4
-cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
 confirmPassword=\u30d1\u30b9\u30ef\u30fc\u30c9 (\u78ba\u8a8d)
 passwordNeedsToBeUpdated=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
 self.pwd.change.success.msg=\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties
index a54d21540a..834af24b0f 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties
@@ -15,7 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 password=Senha
-submit=Alterar
 confirmPassword=Senha (confirmar)
 passwordNeedsToBeUpdated=Senha precisa ser atualizado
 self.pwd.change.success.msg=Senha mudada com sucesso
@@ -23,4 +22,3 @@ self.pwd.change.success.msg=Senha mudada com sucesso
 self.pwd.change.error=Incapaz de completar a mudan\u00e7a de senha
 self.pwd.change.error.msg=Incapaz de completar a mudan\u00e7a de senha
 self.pwd.change.success=Alterado com sucesso
-cancel=Cancelar
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties
index dc396f8f99..c9c5099251 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties
@@ -15,9 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 password=\u041f\u0430\u0440\u043e\u043b\u044c
-# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c
-submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
-cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 #confirmPassword=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c (\u00d0\u00bf\u00d0\u00be\u00d0\u00b4\u00d1\u0082\u00d0\u00b2\u00d0\u00b5\u00d1\u0080\u00d0\u00b6\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5)
 confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435)
 # passwordNeedsToBeUpdated=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c \u00d0\u00b4\u00d0\u00be\u00d0\u00bb\u00d0\u00b6\u00d0\u00b5\u00d0\u00bd \u00d0\u00b1\u00d1\u008b\u00d1\u0082\u00d1\u008c \u00d0\u00b8\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d1\u0091\u00d0\u00bd
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties
index 2a001b7ad0..f8a85d7179 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties
@@ -15,9 +15,9 @@
 # specific language governing permissions and limitations
 # under the License.
 password=Password
-submit=Change
-cancel=Cancel
 self.securityquestion.change.success=Successfully changed
 self.securityquestion.change.error=Unable to change the security question
 self.securityquestion.change.error.msg=Please contact an administrator
 self.securityquestion.change.success.msg=Security question changed successfully
+securityQuestion=Security Question
+securityAnswer=Security Answer
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties
index 6920aca5de..dd175f97de 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties
@@ -15,9 +15,9 @@
 # specific language governing permissions and limitations
 # under the License.
 password=Password
-submit=Cambia
-cancel=Annulla
 self.securityquestion.change.success=Aggiornamento avvenuto con successo
 self.securityquestion.change.error=Errore durante il cambio della domanda di sicurezza
 self.securityquestion.change.error.msg=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema. 
 self.securityquestion.change.success.msg=Aggiornamento della domanda di sicurezza avvenuto con successo
+securityQuestion=Domanda di sicurezza
+securityAnswer=Risposta di sicurezza
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties
index a5a6bcbbf9..fff0798c65 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties
@@ -15,9 +15,9 @@
 # specific language governing permissions and limitations
 # under the License.
 password=\u30d1\u30b9\u30ef\u30fc\u30c9
-submit=\u5909\u66f4
-cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
 self.securityquestion.change.success=\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f
 self.securityquestion.change.error=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5909\u66f4\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093
 self.securityquestion.change.error.msg=\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8\u306e\u78ba\u8a8d\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093
 self.securityquestion.change.success.msg=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u8cea\u554f\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f
+securityQuestion=Security Question
+securityAnswer=Security Answer
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties
index 7ded2ebfb1..f3429a1ef7 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties
@@ -15,9 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 password=Senha
-submit=Alterar
 self.securityquestion.change.success=Alterado com sucesso
 
 self.securityquestion.change.error=Incapaz de completar a mudan\u00e7a de senha
 self.securityquestion.change.error.msg=Incapaz de completar a mudan\u00e7a de senha
 self.securityquestion.change.success.msg=Pergunta de seguran\u00e7a alterada com sucesso
+securityQuestion=Security Question
+securityAnswer=Security Answer
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties
index 616ccfa425..972a36f9ca 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties
@@ -15,10 +15,9 @@
 # specific language governing permissions and limitations
 # under the License.
 password=\u041f\u0430\u0440\u043e\u043b\u044c
-# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c
-submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
-cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 self.securityquestion.change.success=\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043e
 self.securityquestion.change.error=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u043c\u0435\u043d\u0443 \u043f\u0430\u0440\u043e\u043b\u044f
 self.securityquestion.change.error.msg=\u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c
 self.securityquestion.change.success.msg=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d
+securityQuestion=Security Question
+securityAnswer=Security Answer
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html
index c1b74ac627..6037187849 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html
@@ -18,18 +18,18 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-<wicket:extend>
+  <wicket:extend>
     <section class="container-fluid" wicket:id="content">
-        <div class="card card-outline">
-            <div class="card-body">
-                <!-- left column -->
-                <div class="col-md-12">
-                    <div class="col-md-12 column">
-                        <span wicket:id="editUserPanel"></span>
-                    </div>
-                </div>
+      <div class="card card-outline">
+        <div class="card-body">
+          <!-- left column -->
+          <div class="col-md-12">
+            <div class="col-md-12 column">
+              <span wicket:id="editUserPanel"></span>
             </div>
+          </div>
         </div>
+      </div>
     </section>
-</wicket:extend>
+  </wicket:extend>
 </html>
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
index 633e2c5033..b9100c3071 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties
@@ -17,7 +17,3 @@
 overview=Overview
 control=Control
 accessTokens=Access Tokens
-palette.available=Available
-palette.selected=Selected
-submit=Change
-cancel=Cancel
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties
index 899a97cd2b..9f8e983048 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties
@@ -16,11 +16,8 @@
 # under the License.
 username=Username
 password=Password
-submit=Change
-cancel=Cancel
 confirmPassword=Password (confirm)
 passwordNeedsToBeUpdated=Password needs to be updated
 self.pwd.change.success=Password successfully changed
-Cancel=Cancel
 self.pwd.change.error=Unable to complete the change password
 self.pwd.change.error.msg=Please contact an administrator
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties
index bfc6873603..bf7394e52f 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties
@@ -16,12 +16,8 @@
 # under the License.
 username=Username
 password=Password
-submit=Cambia
-cancel=Annulla
 confirmPassword=Password (conferma)
 passwordNeedsToBeUpdated=La password deve essere aggiornata
 self.pwd.change.success=Password aggiornata con successo
-
-Cancel=Annulla
 self.pwd.change.error=Errore durante il cambio password
 self.pwd.change.error.msg=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema. 
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties
index ea0d5bf94f..d6a98bbc76 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties
@@ -16,12 +16,8 @@
 # under the License.
 username=\u30e6\u30fc\u30b6\u30fc\u540d
 password=\u30d1\u30b9\u30ef\u30fc\u30c9
-submit=\u5909\u66f4
-cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
 confirmPassword=\u30d1\u30b9\u30ef\u30fc\u30c9 (\u78ba\u8a8d)
 passwordNeedsToBeUpdated=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
 self.pwd.change.success=\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f
-
-Cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
 self.pwd.change.error=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5909\u66f4\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093
 self.pwd.change.error.msg=\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8\u306e\u78ba\u8a8d\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties
index f5e4aba808..640a826ee1 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties
@@ -16,8 +16,6 @@
 # under the License.
 username=Usu\u00e1rio
 password=Senha
-submit=Alterar
-Cancel=Cancelar
 confirmPassword=Senha (confirmar)
 passwordNeedsToBeUpdated=Senha precisa ser atualizado
 self.pwd.change.success=Senha mudada com sucesso
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties
index 1d7af162ac..ce36ebe4f1 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties
@@ -17,15 +17,10 @@
 username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 # password=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c
 password=\u041f\u0430\u0440\u043e\u043b\u044c
-# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c
-submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
-cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 #confirmPassword=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c (\u00d0\u00bf\u00d0\u00be\u00d0\u00b4\u00d1\u0082\u00d0\u00b2\u00d0\u00b5\u00d1\u0080\u00d0\u00b6\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5)
 confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435)
 # passwordNeedsToBeUpdated=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c \u00d0\u00b4\u00d0\u00be\u00d0\u00bb\u00d0\u00b6\u00d0\u00b5\u00d0\u00bd \u00d0\u00b1\u00d1\u008b\u00d1\u0082\u00d1\u008c \u00d0\u00b8\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d1\u0091\u00d0\u00bd
 passwordNeedsToBeUpdated=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0451\u043d
 self.pwd.change.success=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d
-
-Cancel=\u041e\u0442\u043c\u0435\u043d\u0430
 self.pwd.change.error=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u043c\u0435\u043d\u0443 \u043f\u0430\u0440\u043e\u043b\u044f
 self.pwd.change.error.msg=\u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
index c5da696e65..59b2080e7d 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
@@ -18,8 +18,6 @@ confirm-reset=Confirm password reset
 password=Password
 confirm-password=Confirm password
 password-strength=Password strength:
-cancel=Cancel
-submit=Submit
 self.confirm.pwd.reset.success=Password Changed!
 self.confirm.pwd.reset.success.msg=Password successfully changed
 self.confirm.pwd.reset.error.empty=No token was specified in the url, cannot access to the requested page
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
index 9500f0c356..13baa1f0ab 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
@@ -18,8 +18,6 @@ confirm-reset=Conferma reset della password
 password=Password
 confirm-password=Conferma password
 password-strength=Sicurezza della password:
-cancel=Annulla
-submit=Invia
 self.confirm.pwd.reset.success=Password \u00e8 stata modificata
 self.confirm.pwd.reset.success.msg=Cambio password eseguito con successo
 self.confirm.pwd.reset.error.empty=Nessun token \u00e8 specificato nell'url, non \u00e8 possibile accedere alla pagina richiesta
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties
index 7703a33320..a957cc1aa9 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties
@@ -18,8 +18,6 @@ confirm-reset=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u518d\u8a2d\u5b9a\u3092\u78ba
 password=\u30d1\u30b9\u30ef\u30fc\u30c9
 confirm-password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u8a8d\u8a3c\u3059\u308b
 password-strength=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5f37\u5ea6\uff1a
-cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
-submit=\u63d0\u51fa\u3059\u308b
 self.confirm.pwd.reset.success=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u307e\u3057\u305f
 self.confirm.pwd.reset.error.empty=URL\u306b\u30c8\u30fc\u30af\u30f3\u304c\u6307\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u8981\u6c42\u3055\u308c\u305f\u30da\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u305b\u3093
 self.confirm.pwd.reset.success.msg=Password Changed!
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties
index 88202f9118..e219188cda 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties
@@ -18,8 +18,6 @@ confirm-reset=Confirme a redefini\u00e7\u00e3o da senha
 password=Senha
 confirm-password=Confirme a Senha
 password-strength=For\u00e7a da senha:
-cancel=Cancelar
-submit=Enviar
 self.confirm.pwd.reset.success=Senha redefinida com sucesso
 self.confirm.pwd.reset.success.msg=Senha redefinida com sucesso
 self.confirm.pwd.reset.error.empty=Nenhum token foi especificado na URL, n\u00e3o pode acessar a p\u00e1gina solicitada
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties
index a1445b84fa..03f1807d88 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties
@@ -18,8 +18,6 @@ confirm-reset=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435
 password=\u043f\u0430\u0440\u043e\u043b\u044c
 confirm-password=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u041f\u0430\u0440\u043e\u043b\u044c
 password-strength=\u041d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c \u041f\u0430\u0440\u043e\u043b\u044f:
-cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
-submit=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c
 self.confirm.pwd.reset.success=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0431\u0440\u043e\u0448\u0435\u043d
 self.confirm.pwd.reset.success.msg=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0431\u0440\u043e\u0448\u0435\u043d
 self.confirm.pwd.reset.error.empty=\u0412 URL \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u0442\u043e\u043a\u0435\u043d, \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties
index 73ca456a86..5999bc1df1 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties
@@ -19,5 +19,3 @@ securityQuestion=Security Question
 securityAnswer=Security Answer
 reload=Reload
 not.loading=Not loading?
-submit=Submit
-cancel=Cancel
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties
index 73ca456a86..5999bc1df1 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties
@@ -19,5 +19,3 @@ securityQuestion=Security Question
 securityAnswer=Security Answer
 reload=Reload
 not.loading=Not loading?
-submit=Submit
-cancel=Cancel
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties
index 5cc8c26436..d5e4542c3d 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties
@@ -19,5 +19,3 @@ securityQuestion=Domanda di sicurezza
 securityAnswer=Risposta di sicurezza
 reload=Ricarica
 not.loading=Non carica?
-submit=Salva
-cancel=Annulla
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties
index 54ca2b3dc0..8adddfa539 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties
@@ -19,5 +19,3 @@ securityQuestion=\u79d8\u5bc6\u306e\u8cea\u554f
 securityAnswer=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u56de\u7b54
 reload=\u30ea\u30ed\u30fc\u30c9
 not.loading=\u30ed\u30fc\u30c9\u3057\u3066\u3044\u307e\u305b\u3093\u304b\uff1f
-submit=\u63d0\u51fa\u3059\u308b
-cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties
index 0a1b647b44..18507c777b 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties
@@ -19,5 +19,3 @@ securityQuestion=Pergunta de Seguran\u00e7a
 securityAnswer=Resposta de seguran\u00e7a
 reload=recarregar
 not.loading=N\u00e3o est\u00e1 carregando?
-submit=Enviar
-cancel=Cancelar
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties
index 9287f4907a..8615e44535 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties
@@ -19,5 +19,3 @@ securityQuestion=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0
 securityAnswer=\u041e\u0442\u0432\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438
 reload=\u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c
 not.loading=\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f?
-submit=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c
-cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties
index f2447ea821..8d767e27a2 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties
@@ -16,9 +16,6 @@
 # under the License.
 username=Username
 password=Password
-submit=Change
-cancel=Cancel
 confirmPassword=Password (confirm)
 passwordNeedsToBeUpdated=Password needs to be updated
 self.pwd.change.success=Password successfully changed
-editchangepassword=Change password
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties
index 0d65dc419c..dd7759803f 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties
@@ -16,8 +16,6 @@
 # under the License.
 username=Username
 password=Password
-submit=Cambia
-cancel=Annulla
 confirmPassword=Password (conferma)
 passwordNeedsToBeUpdated=La password deve essere aggiornata
 self.pwd.change.success=Password aggiornata con successo
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties
index 34bb07ced3..6d3d9d66f4 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties
@@ -16,8 +16,6 @@
 # under the License.
 username=\u30e6\u30fc\u30b6\u30fc\u540d
 password=\u30d1\u30b9\u30ef\u30fc\u30c9
-submit=\u5909\u66f4
-cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
 confirmPassword=\u30d1\u30b9\u30ef\u30fc\u30c9 (\u78ba\u8a8d)
 passwordNeedsToBeUpdated=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
 self.pwd.change.success=\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties
index 3390349529..7e48492d1e 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties
@@ -16,8 +16,6 @@
 # under the License.
 username=Usu\u00e1rio
 password=Senha
-submit=Alterar
-Cancel=Cancelar
 confirmPassword=Senha (confirmar)
 passwordNeedsToBeUpdated=Senha precisa ser atualizado
 self.pwd.change.success=Senha mudada com sucesso
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties
index 6f199c603d..e3062e56a9 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties
@@ -17,9 +17,6 @@
 username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 # password=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c
 password=\u041f\u0430\u0440\u043e\u043b\u044c
-# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c
-submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
-cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 #confirmPassword=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c (\u00d0\u00bf\u00d0\u00be\u00d0\u00b4\u00d1\u0082\u00d0\u00b2\u00d0\u00b5\u00d1\u0080\u00d0\u00b6\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5)
 confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435)
 # passwordNeedsToBeUpdated=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c \u00d0\u00b4\u00d0\u00be\u00d0\u00bb\u00d0\u00b6\u00d0\u00b5\u00d0\u00bd \u00d0\u00b1\u00d1\u008b\u00d1\u0082\u00d1\u008c \u00d0\u00b8\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d1\u0091\u00d0\u00bd
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html
index 5aaf7de965..aafa6fc103 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html
@@ -27,72 +27,82 @@ under the License.
     </div>
 
     <!-- Sidebar -->
-      <div class="sidebar-wrapper" data-overlayscrollbars="host">
-          <div class="os-size-observer os-size-observer-appear"><div class="os-size-observer-listener ltr"></div></div>
+    <div class="sidebar-wrapper" data-overlayscrollbars="host">
+      <div class="os-size-observer os-size-observer-appear"><div class="os-size-observer-listener ltr"></div></div>
 
-          <div data-overlayscrollbars-viewport="scrollbarHidden">
-              <!-- Sidebar Menu -->
-              <nav class="mt-2">
-                  <ul class="nav sidebar-menu flex-column" data-lte-toggle="treeview" role="menu"
-                      data-accordion="false">
-                      <li class="nav-item" wicket:id="dashboardLI"><a href="#" wicket:id="home" class="nav-link"><i
-                              class="fa fa-id-card nav-icon"></i>
-                          <p>
-                              <wicket:message key="home"/>
-                          </p>
-                      </a></li>
-                      <li wicket:id="profileLI" class="nav-item">
-                          <a id="profileLink" href="#" class="nav-link"><i class="nav-icon fa fa-user"></i>
-                              <p>
-                                  <wicket:message key="profile"/>
-                              </p>
-                              <i class="nav-arrow fas fa-angle-left right"></i></a>
-                          <ul wicket:id="profileUL" class="nav nav-treeview">
-                              <li class="nav-item" wicket:id="edituserLI"><a href="#" class="nav-link"
-                                                                             wicket:id="edituser"><i
-                                      class="nav-icon fa fa-edit"></i>
-                                  <p>
-                                      <wicket:message key="edituser"/>
-                                  </p>
-                              </a></li>
-                              <li class="nav-item" wicket:id="editchangepasswordLI"><a href="#" class="nav-link"
-                                                                                       wicket:id="editchangepassword"><i
-                                      class="nav-icon fas fa-key"></i>
-                                  <p>
-                                      <wicket:message key="editchangepassword"/>
-                                  </p>
-                              </a></li>
-                              <li class="nav-item" wicket:id="editsecurityquestionLI"><a href="#" class="nav-link"
-                                                                                         wicket:id="editsecurityquestion"><i
-                                      class="nav-icon fa fa-lock"></i>
-                                  <p>
-                                      <wicket:message key="editsecurityquestion"/>
-                                  </p>
-                              </a></li>
-                          </ul>
-                      </li>
+      <div data-overlayscrollbars-viewport="scrollbarHidden">
+        <!-- Sidebar Menu -->
+        <nav class="mt-2">
+          <ul class="nav sidebar-menu flex-column" data-lte-toggle="treeview" role="menu"
+              data-accordion="false">
+            <li class="nav-item" wicket:id="dashboardLI"><a href="#" wicket:id="home" class="nav-link"><i
+                  class="fa fa-id-card nav-icon"></i>
+                <p>
+                  <wicket:message key="home"/>
+                </p>
+              </a></li>
+            <li wicket:id="profileLI" class="nav-item">
+              <a id="profileLink" href="#" class="nav-link"><i class="nav-icon fa fa-user"></i>
+                <p>
+                  <wicket:message key="profile"/>
+                </p>
+                <i class="nav-arrow fas fa-angle-left right"></i></a>
+              <ul wicket:id="profileUL" class="nav nav-treeview">
+                <li class="nav-item" wicket:id="edituserLI"><a href="#" class="nav-link"
+                                                               wicket:id="edituser"><i
+                      class="nav-icon fa fa-edit"></i>
+                    <p>
+                      <wicket:message key="edituser"/>
+                    </p>
+                  </a></li>
+                <li class="nav-item" wicket:id="editchangepasswordLI">
+                  <a href="#" class="nav-link" wicket:id="editchangepassword"><i class="nav-icon fas fa-key"></i>
+                    <p>
+                      <wicket:message key="editchangepassword"/>
+                    </p>
+                  </a></li>
+                <li class="nav-item" wicket:id="editsecurityquestionLI">
+                  <a href="#" class="nav-link" wicket:id="editsecurityquestion"><i class="nav-icon fa fa-lock"></i>
+                    <p>
+                      <wicket:message key="editsecurityquestion"/>
+                    </p>
+                  </a></li>
+              </ul>
+            </li>
 
-                      <wicket:container wicket:id="extPages">
-                          <li class="nav-item" wicket:id="extPageLI">
-                              <a href="#" class="nav-link" wicket:id="extPage"><i wicket:id="extPageIcon"></i>
-                                  <p wicket:id="extPageLabel"/></a>
-                          </li>
-                      </wicket:container>
-                  </ul>
-              </nav>
-          </div>
-          <div class="os-scrollbar os-scrollbar-horizontal os-theme-light os-scrollbar-auto-hide os-scrollbar-handle-interactive os-scrollbar-track-interactive os-scrollbar-cornerless os-scrollbar-unusable os-scrollbar-auto-hide-hidden">
-              <div class="os-scrollbar-track">
-                  <div class="os-scrollbar-handle" style="width: 100%;"></div>
-              </div>
-          </div>
-          <div class="os-scrollbar os-scrollbar-vertical os-theme-light os-scrollbar-auto-hide os-scrollbar-handle-interactive os-scrollbar-track-interactive os-scrollbar-visible os-scrollbar-cornerless os-scrollbar-auto-hide-hidden">
-              <div class="os-scrollbar-track">
-                  <div class="os-scrollbar-handle" style="height: 39.633%;"></div>
-              </div>
-          </div>
+            <wicket:container wicket:id="idmPages">
+              <li class="nav-item" wicket:id="idmPageLI">
+                <a href="#" class="nav-link" wicket:id="idmPage"><i wicket:id="idmPageIcon"></i>
+                  <p wicket:id="idmPageLabel"/></a>
+              </li>
+            </wicket:container>
+            <wicket:container wicket:id="amPages">
+              <li class="nav-item" wicket:id="amPageLI">
+                <a href="#" class="nav-link" wicket:id="amPage"><i wicket:id="amPageIcon"></i>
+                  <p wicket:id="amPageLabel"/></a>
+              </li>
+            </wicket:container>
+            <wicket:container wicket:id="extPages">
+              <li class="nav-item" wicket:id="extPageLI">
+                <a href="#" class="nav-link" wicket:id="extPage"><i wicket:id="extPageIcon"></i>
+                  <p wicket:id="extPageLabel"/></a>
+              </li>
+            </wicket:container>
+          </ul>
+        </nav>
       </div>
-      <!-- /.sidebar-menu -->
+      <div class="os-scrollbar os-scrollbar-horizontal os-theme-light os-scrollbar-auto-hide os-scrollbar-handle-interactive os-scrollbar-track-interactive os-scrollbar-cornerless os-scrollbar-unusable os-scrollbar-auto-hide-hidden">
+        <div class="os-scrollbar-track">
+          <div class="os-scrollbar-handle" style="width: 100%;"></div>
+        </div>
+      </div>
+      <div class="os-scrollbar os-scrollbar-vertical os-theme-light os-scrollbar-auto-hide os-scrollbar-handle-interactive os-scrollbar-track-interactive os-scrollbar-visible os-scrollbar-cornerless os-scrollbar-auto-hide-hidden">
+        <div class="os-scrollbar-track">
+          <div class="os-scrollbar-handle" style="height: 39.633%;"></div>
+        </div>
+      </div>
+    </div>
+    <!-- /.sidebar-menu -->
     <!-- /.sidebar -->
   </wicket:panel>
 </html>
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails.properties
index 8d7410c180..2b2fb2d5a1 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails.properties
@@ -20,4 +20,4 @@ confirmPassword=Password (confirm)
 password.change=Password management
 password.change.warning=Password value will be sent to all associated resources
 storePasswordInSyncope=Store password in Syncope
-destinationRealm=Destination realm
+destinationRealm=Realm
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_it.properties
index d760f898a5..96ed1bf426 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_it.properties
@@ -20,4 +20,4 @@ confirmPassword=Password (conferma)
 password.change=Gestisci password
 password.change.warning=La password sar\u00e0 inviata a tutte le risorse associate
 storePasswordInSyncope=Salva password in Syncope
-destinationRealm=Realm di destinazione
+destinationRealm=Realm
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ja.properties
index b0b0e62981..f373533710 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ja.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ja.properties
@@ -20,4 +20,4 @@ confirmPassword=\u30d1\u30b9\u30ef\u30fc\u30c9 (\u78ba\u8a8d)
 password.change=\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406
 password.change.warning=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5024\u306f\u3059\u3079\u3066\u306e\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30ea\u30bd\u30fc\u30b9\u306b\u9001\u4fe1\u3055\u308c\u307e\u3059
 storePasswordInSyncope=Syncope \u306b\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u683c\u7d0d
-destinationRealm=\u5b9b\u5148\u30ec\u30eb\u30e0
+destinationRealm=Realm
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_pt_BR.properties
index 6cecec35b2..c9a4199609 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_pt_BR.properties
@@ -20,4 +20,4 @@ confirmPassword=Senha (confirmar)
 password.change=Gest\u00e3o password
 password.change.warning=Password value will be sent to all associated resources
 storePasswordInSyncope=Salvar senha in Syncope
-destinationRealm=Destination realm
+destinationRealm=Realm
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ru.properties
index cc2ffa278c..ac258fc283 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/UserDetails_ru.properties
@@ -20,4 +20,4 @@ confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u
 password.change=\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c
 password.change.warning=Password value will be sent to all associated resources
 storePasswordInSyncope=\u0425\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c \u0432 Syncope
-destinationRealm=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f
+destinationRealm=Realm
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/widgets/UserProfileWidget.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/widgets/UserProfileWidget.html
index 7b1dbf7d4a..d68fbe5ad2 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/widgets/UserProfileWidget.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/widgets/UserProfileWidget.html
@@ -17,41 +17,33 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-<wicket:panel>
+  <wicket:panel>
     <div wicket:id="userProfile">
-        <div class="formcard col-md-4">
-            <header class="card-container bg-danger">
-                <label class="form-label card-header-style">
-                    <wicket:message key="welcome"/>
-                    <b><label class="form-label card-header-style" wicket:id="welcome"/></b></label>
-            </header>
-            <div class="card-container-body">
-                <div>
-                    <div class="box-footer no-padding no-border-top">
-                        <ul class="nav navbar-nav flex-column">
-                            <li class="nav-item"><a class="nav-link disabled" href="#">
-                                <wicket:message key="name"/>
-                                :
-                                <span class="float-end badge"><label class="form-label"
-                                                                     wicket:id="username"/></span></a>
-                            </li>
-                            <li class="nav-item"><a class="nav-link disabled" href="#">
-                                <wicket:message key="lastLoginDate"/>
-                                :
-                                <span class="float-end badge"><label class="form-label"
-                                                                     wicket:id="lastLoginDate"/></span></a>
-                            </li>
-                            <li class="nav-item"><a class="nav-link disabled" href="#">
-                                <wicket:message key="lastChangePwdDate"/>
-                                :
-                                <span class="float-end badge"><label class="form-label"
-                                                                     wicket:id="changePwdDate"/></span></a>
-                            </li>
-                        </ul>
-                    </div>
-                </div>
+      <div class="formcard col-md-4">
+        <header class="card-container bg-danger">
+          <label class="form-label card-header-style">
+            <wicket:message key="welcome"/>
+            <b><label class="form-label card-header-style" wicket:id="welcome"/></b></label>
+        </header>
+        <div class="card-container-body">
+          <div>
+            <div class="box-footer no-padding no-border-top">
+              <ul class="nav navbar-nav flex-column">
+                <li class="nav-item"><a class="nav-link disabled" href="#">
+                    <wicket:message key="lastLoginDate"/>
+                    :
+                    <span class="float-end badge"><label class="form-label" wicket:id="lastLoginDate"/></span></a>
+                </li>
+                <li class="nav-item"><a class="nav-link disabled" href="#">
+                    <wicket:message key="lastChangePwdDate"/>
+                    :
+                    <span class="float-end badge"><label class="form-label" wicket:id="changePwdDate"/></span></a>
+                </li>
+              </ul>
             </div>
+          </div>
         </div>
+      </div>
     </div>
-</wicket:panel>
+  </wicket:panel>
 </html>
diff --git a/client/idrepo/enduser/src/test/resources/enduser-debug.properties b/client/idrepo/enduser/src/test/resources/enduser-debug.properties
index a8905a8f27..e34599c3d0 100644
--- a/client/idrepo/enduser/src/test/resources/enduser-debug.properties
+++ b/client/idrepo/enduser/src/test/resources/enduser-debug.properties
@@ -17,8 +17,8 @@
 
 management.endpoints.web.exposure.include=health,info,beans,env,loggers
 
-#keymaster.address=http://localhost:9080/syncope/rest/keymaster
-keymaster.address=https://localhost:9443/syncope/rest/keymaster
+keymaster.address=http://localhost:9080/syncope/rest/keymaster
+#keymaster.address=https://localhost:9443/syncope/rest/keymaster
 keymaster.username=${anonymousUser}
 keymaster.password=${anonymousKey}
 
diff --git a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.java
index 51936a1284..765040caf5 100644
--- a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.java
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractOIDCSSOLoginFormPanel.java
@@ -68,10 +68,10 @@ public abstract class AbstractOIDCSSOLoginFormPanel extends BaseSSOLoginFormPane
 
             @Override
             public OIDCC4UIProviderTO getObject(final String id,
-                                                final IModel<? extends List<? extends OIDCC4UIProviderTO>> choices) {
+                    final IModel<? extends List<? extends OIDCC4UIProviderTO>> choices) {
 
                 return choices.getObject().stream().
-                    filter(object -> object.getName().equals(id)).findFirst().orElse(null);
+                        filter(object -> object.getName().equals(id)).findFirst().orElse(null);
             }
         });
 
@@ -84,8 +84,10 @@ public abstract class AbstractOIDCSSOLoginFormPanel extends BaseSSOLoginFormPane
                 if (model.getObject() != null) {
                     try {
                         RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler(
-                                UrlUtils.rewriteToContextRelative(OIDCC4UIConstants.URL_CONTEXT + "/login?op="
-                                        + URLEncoder.encode(model.getObject().getName(), StandardCharsets.UTF_8),
+                                UrlUtils.rewriteToContextRelative(OIDCC4UIConstants.URL_CONTEXT + "/login?"
+                                        + OIDCC4UIConstants.PARAM_OP + "="
+                                        + URLEncoder.encode(model.getObject().getName(), StandardCharsets.UTF_8)
+                                        + "&" + OIDCC4UIConstants.PARAM_REAUTH + "=" + reauth,
                                         RequestCycle.get())));
                     } catch (Exception e) {
                         LOG.error("Could not redirect to the selected OP {}", model.getObject().getName(), e);
diff --git a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/OIDCC4UIConstants.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/OIDCC4UIConstants.java
index fddb6efa73..c555d3bd05 100644
--- a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/OIDCC4UIConstants.java
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/OIDCC4UIConstants.java
@@ -24,6 +24,8 @@ public final class OIDCC4UIConstants {
 
     public static final String PARAM_OP = "op";
 
+    public static final String PARAM_REAUTH = "reauth";
+
     public static final String OIDCC4UI_JWT = "oidcc4ui.jwt";
 
     public static final String OIDCC4UI_SLO_SUPPORTED = "oidcc4ui.sloSupported";
diff --git a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LoginResource.java b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LoginResource.java
index 1b6e7bec00..2e0db8252d 100644
--- a/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LoginResource.java
+++ b/ext/oidcc4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/oidcc4ui/LoginResource.java
@@ -40,15 +40,18 @@ public class LoginResource extends AbstractResource {
 
     @Override
     protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        String op = attributes.getRequest().getQueryParameters().
-                getParameterValue(OIDCC4UIConstants.PARAM_OP).toString();
-
         HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
         String redirectURI = StringUtils.substringBefore(
                 request.getRequestURL().toString(), "/login") + "/code-consumer";
 
+        String op = attributes.getRequest().getQueryParameters().
+                getParameterValue(OIDCC4UIConstants.PARAM_OP).toString();
+
+        boolean reauth = attributes.getRequest().getQueryParameters().
+                getParameterValue(OIDCC4UIConstants.PARAM_REAUTH).toBoolean(false);
+
         OIDCC4UIService service = BaseSession.class.cast(Session.get()).getAnonymousService(OIDCC4UIService.class);
-        OIDCRequest loginRequest = service.createLoginRequest(redirectURI, op);
+        OIDCRequest loginRequest = service.createLoginRequest(redirectURI, op, reauth);
 
         Session.get().setAttribute(OIDCConstants.OP, op);
 
diff --git a/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
index 5096ec10a3..60e207a094 100644
--- a/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
+++ b/ext/oidcc4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/OIDCClientLogin.java
@@ -55,6 +55,8 @@ public class OIDCClientLogin extends WebPage {
                 SyncopeEnduserSession.get().setAttribute(Constants.BEFORE_LOGOUT_PAGE, OIDCClientBeforeLogout.class);
             }
 
+            SyncopeEnduserSession.get().setLastReauth();
+
             // If login has been called because the user was not yet logged in, than continue to the
             // original destination, otherwise to the Home page
             continueToOriginalDestination();
diff --git a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UILogic.java b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UILogic.java
index 2174a0dbef..4af951e0b7 100644
--- a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UILogic.java
+++ b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/OIDCC4UILogic.java
@@ -52,10 +52,13 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.AuthDataAccessor;
 import org.pac4j.core.context.CallContext;
+import org.pac4j.core.context.WebContext;
 import org.pac4j.core.exception.http.WithLocationAction;
 import org.pac4j.oidc.client.OidcClient;
+import org.pac4j.oidc.config.OidcConfiguration;
 import org.pac4j.oidc.credentials.OidcCredentials;
 import org.pac4j.oidc.profile.OidcProfile;
+import org.pac4j.oidc.redirect.OidcRedirectionActionBuilder;
 import org.springframework.security.access.prepost.PreAuthorize;
 
 public class OIDCC4UILogic extends AbstractTransactionalLogic<EntityTO> {
@@ -105,7 +108,7 @@ public class OIDCC4UILogic extends AbstractTransactionalLogic<EntityTO> {
     }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
-    public OIDCRequest createLoginRequest(final String redirectURI, final String opName) {
+    public OIDCRequest createLoginRequest(final String redirectURI, final String opName, final boolean reauth) {
         // 0. look for OP
         OIDCC4UIProvider op = opDAO.findByName(opName).
                 orElseThrow(() -> new NotFoundException("OIDC Provider '" + opName + '\''));
@@ -113,6 +116,19 @@ public class OIDCC4UILogic extends AbstractTransactionalLogic<EntityTO> {
         // 1. look for OidcClient
         OidcClient oidcClient = getOidcClient(oidcClientCacheLogin, op, redirectURI);
 
+        oidcClient.setRedirectionActionBuilder(new OidcRedirectionActionBuilder(oidcClient) {
+
+            @Override
+            protected Map<String, String> buildParams(final WebContext webContext) {
+                Map<String, String> params = super.buildParams(webContext);
+                if (reauth) {
+                    params.put(OidcConfiguration.PROMPT, "login");
+                    params.put(OidcConfiguration.MAX_AGE, "0");
+                }
+                return params;
+            }
+        });
+
         // 2. create OIDCRequest
         WithLocationAction action = oidcClient.getRedirectionAction(
                 new CallContext(new OIDCC4UIContext(), NoOpSessionStore.INSTANCE)).
@@ -180,7 +196,7 @@ public class OIDCC4UILogic extends AbstractTransactionalLogic<EntityTO> {
 
         List<String> matchingUsers = Optional.ofNullable(keyValue).
                 map(k -> userManager.findMatchingUser(k, op.getConnObjectKeyItem().get())).
-            orElseGet(List::of);
+                orElseGet(List::of);
         LOG.debug("Found {} matching users for {}", matchingUsers.size(), keyValue);
 
         // 3b. not found: create or selfreg if configured
diff --git a/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIService.java b/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIService.java
index 7772e9bdae..0afb715764 100644
--- a/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIService.java
+++ b/ext/oidcc4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/OIDCC4UIService.java
@@ -21,6 +21,7 @@ package org.apache.syncope.common.rest.api.service;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import io.swagger.v3.oas.annotations.security.SecurityRequirements;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.ws.rs.DefaultValue;
 import jakarta.ws.rs.POST;
 import jakarta.ws.rs.Path;
 import jakarta.ws.rs.Produces;
@@ -46,6 +47,7 @@ public interface OIDCC4UIService extends JAXRSService {
      *
      * @param redirectURI redirect URI
      * @param op OpenID Connect Provider
+     * @param reauth whether max_age=0 and prompt=login shall be set on the request
      * @return OpenID Connect authentication request
      */
     @POST
@@ -53,7 +55,8 @@ public interface OIDCC4UIService extends JAXRSService {
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     OIDCRequest createLoginRequest(
             @QueryParam(OIDCConstants.REDIRECT_URI) String redirectURI,
-            @QueryParam(OIDCConstants.OP) String op);
+            @QueryParam(OIDCConstants.OP) String op,
+            @DefaultValue("false") @QueryParam("reauth") boolean reauth);
 
     /**
      * Uses the provided authorization code to go through the OpenID Connect tokens process and finally creates JWT for
diff --git a/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIServiceImpl.java b/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIServiceImpl.java
index 3331d0cba2..a27beca5c7 100644
--- a/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIServiceImpl.java
+++ b/ext/oidcc4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCC4UIServiceImpl.java
@@ -34,8 +34,8 @@ public class OIDCC4UIServiceImpl extends AbstractService implements OIDCC4UIServ
     }
 
     @Override
-    public OIDCRequest createLoginRequest(final String redirectURI, final String op) {
-        return logic.createLoginRequest(redirectURI, op);
+    public OIDCRequest createLoginRequest(final String redirectURI, final String op, final boolean reauth) {
+        return logic.createLoginRequest(redirectURI, op, reauth);
     }
 
     @Override
diff --git a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/SAML2SP4UIConstants.java b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/SAML2SP4UIConstants.java
index 073dca6388..c67fbd0b92 100644
--- a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/SAML2SP4UIConstants.java
+++ b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/SAML2SP4UIConstants.java
@@ -24,6 +24,8 @@ public final class SAML2SP4UIConstants {
 
     public static final String PARAM_IDP = "idp";
 
+    public static final String PARAM_REAUTH = "reauth";
+
     public static final String SAML2SP4UI_JWT = "saml2sp4ui.jwt";
 
     public static final String SAML2SP4UI_SLO_SUPPORTED = "saml2sp4ui.sloSupported";
diff --git a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java
index 8f3d77a07e..46673ed751 100644
--- a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java
+++ b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/AbstractSAMLSSOLoginFormPanel.java
@@ -69,10 +69,10 @@ public abstract class AbstractSAMLSSOLoginFormPanel extends BaseSSOLoginFormPane
 
             @Override
             public SAML2SP4UIIdPTO getObject(
-                final String id, final IModel<? extends List<? extends SAML2SP4UIIdPTO>> choices) {
+                    final String id, final IModel<? extends List<? extends SAML2SP4UIIdPTO>> choices) {
 
                 return choices.getObject().stream().
-                    filter(idp -> idp.getEntityID().equals(id)).findFirst().orElse(null);
+                        filter(idp -> idp.getEntityID().equals(id)).findFirst().orElse(null);
             }
         });
         idps.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
@@ -84,9 +84,10 @@ public abstract class AbstractSAMLSSOLoginFormPanel extends BaseSSOLoginFormPane
                 if (model.getObject() != null) {
                     try {
                         RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler(
-                                UrlUtils.rewriteToContextRelative(SAML2SP4UIConstants.URL_CONTEXT + "/login?idp="
-                                        + URLEncoder.encode(
-                                                model.getObject().getEntityID(), StandardCharsets.UTF_8),
+                                UrlUtils.rewriteToContextRelative(SAML2SP4UIConstants.URL_CONTEXT + "/login?"
+                                        + SAML2SP4UIConstants.PARAM_IDP + "=" + URLEncoder.encode(
+                                                model.getObject().getEntityID(), StandardCharsets.UTF_8)
+                                        + "&" + SAML2SP4UIConstants.PARAM_REAUTH + "=" + reauth,
                                         RequestCycle.get())));
                     } catch (Exception e) {
                         LOG.error("Could not redirect to the selected IdP {}", model.getObject().getEntityID(), e);
diff --git a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/saml2sp4ui/LoginResource.java b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/saml2sp4ui/LoginResource.java
index 0bd1b6f344..aa2b6e512b 100644
--- a/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/saml2sp4ui/LoginResource.java
+++ b/ext/saml2sp4ui/client-common-ui/src/main/java/org/apache/syncope/client/ui/commons/resources/saml2sp4ui/LoginResource.java
@@ -35,8 +35,10 @@ public class LoginResource extends AbstractSAML2SP4UIResource {
     protected ResourceResponse newResourceResponse(final Attributes attributes) {
         String idp = attributes.getRequest().getQueryParameters().
                 getParameterValue(SAML2SP4UIConstants.PARAM_IDP).toString();
+        boolean reauth = attributes.getRequest().getQueryParameters().
+                getParameterValue(SAML2SP4UIConstants.PARAM_REAUTH).toBoolean(false);
 
         SAML2SP4UIService service = BaseSession.class.cast(Session.get()).getAnonymousService(SAML2SP4UIService.class);
-        return send(service.createLoginRequest(spEntityID(attributes), SAML2SP4UIConstants.URL_CONTEXT, idp));
+        return send(service.createLoginRequest(spEntityID(attributes), SAML2SP4UIConstants.URL_CONTEXT, idp, reauth));
     }
 }
diff --git a/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/SAML2SPLogin.java b/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/SAML2SPLogin.java
index 9b10c2c056..d8aa14bdad 100644
--- a/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/SAML2SPLogin.java
+++ b/ext/saml2sp4ui/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/SAML2SPLogin.java
@@ -55,6 +55,8 @@ public class SAML2SPLogin extends WebPage {
                 SyncopeEnduserSession.get().setAttribute(Constants.BEFORE_LOGOUT_PAGE, SAML2SPBeforeLogout.class);
             }
 
+            SyncopeEnduserSession.get().setLastReauth();
+
             // If login has been called because the user was not yet logged in, than continue to the
             // original destination, otherwise to the Home page
             continueToOriginalDestination();
diff --git a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
index 277581c7d1..0944df22d6 100644
--- a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
+++ b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
@@ -65,7 +65,6 @@ import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.saml2.core.AuthnRequest;
 import org.opensaml.saml.saml2.core.LogoutResponse;
 import org.opensaml.saml.saml2.core.NameID;
-import org.opensaml.saml.saml2.core.RequestedAuthnContext;
 import org.opensaml.saml.saml2.core.StatusCode;
 import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
@@ -274,7 +273,8 @@ public class SAML2SP4UILogic extends AbstractSAML2SP4UILogic {
     public SAML2Request createLoginRequest(
             final String spEntityID,
             final String urlContext,
-            final String idpEntityID) {
+            final String idpEntityID,
+            final boolean reauth) {
 
         // 0. look for IdP
         SAML2SP4UIIdP idp = Optional.ofNullable(idpDAO.findByEntityID(idpEntityID)).
@@ -283,24 +283,23 @@ public class SAML2SP4UILogic extends AbstractSAML2SP4UILogic {
         // 1. look for configured client
         SAML2Client saml2Client = getSAML2Client(saml2ClientCacheLogin, idp, spEntityID, urlContext);
 
-        getRequestedAuthnContextProvider(idp).ifPresent(requestedAuthnContextProvider -> {
-            RequestedAuthnContext requestedAuthnContext = requestedAuthnContextProvider.get();
-            saml2Client.setRedirectionActionBuilder(new SAML2RedirectionActionBuilder(saml2Client) {
-
-                @Override
-                public Optional<RedirectionAction> getRedirectionAction(final CallContext ctx) {
-                    this.saml2ObjectBuilder = new SAML2AuthnRequestBuilder() {
-
-                        @Override
-                        public AuthnRequest build(final SAML2MessageContext context) {
-                            AuthnRequest authnRequest = super.build(context);
-                            authnRequest.setRequestedAuthnContext(requestedAuthnContext);
-                            return authnRequest;
-                        }
-                    };
-                    return super.getRedirectionAction(ctx);
-                }
-            });
+        saml2Client.setRedirectionActionBuilder(new SAML2RedirectionActionBuilder(saml2Client) {
+
+            @Override
+            public Optional<RedirectionAction> getRedirectionAction(final CallContext ctx) {
+                this.saml2ObjectBuilder = new SAML2AuthnRequestBuilder() {
+
+                    @Override
+                    public AuthnRequest build(final SAML2MessageContext context) {
+                        AuthnRequest authnRequest = super.build(context);
+                        authnRequest.setForceAuthn(reauth);
+                        getRequestedAuthnContextProvider(idp).
+                                ifPresent(provider -> authnRequest.setRequestedAuthnContext(provider.get()));
+                        return authnRequest;
+                    }
+                };
+                return super.getRedirectionAction(ctx);
+            }
         });
 
         // 2. create AuthnRequest
@@ -386,7 +385,7 @@ public class SAML2SP4UILogic extends AbstractSAML2SP4UILogic {
 
         List<String> matchingUsers = Optional.ofNullable(keyValue).
                 map(k -> userManager.findMatchingUser(k, idp.getKey())).
-            orElseGet(List::of);
+                orElseGet(List::of);
         LOG.debug("Found {} matching users for {}", matchingUsers.size(), keyValue);
 
         String username;
diff --git a/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIService.java b/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIService.java
index 9a82dd040f..e80e7e7416 100644
--- a/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIService.java
+++ b/ext/saml2sp4ui/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SP4UIService.java
@@ -24,6 +24,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import io.swagger.v3.oas.annotations.security.SecurityRequirements;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DefaultValue;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
 import jakarta.ws.rs.Path;
@@ -60,9 +61,10 @@ public interface SAML2SP4UIService extends JAXRSService {
     /**
      * Generates SAML 2.0 authentication request for the IdP matching the provided entity ID.
      *
-     * @param spEntityID SAML 2.0 SP entity ID.
+     * @param spEntityID SAML 2.0 SP entity ID
      * @param urlContext SAML 2.0 SP agent URL context
-     * @param idpEntityID SAML 2.0 IdP entity ID.
+     * @param idpEntityID SAML 2.0 IdP entity ID
+     * @param reauth whether ForceAuthn shall be set on the request
      * @return SAML 2.0 authentication request
      */
     @POST
@@ -71,7 +73,8 @@ public interface SAML2SP4UIService extends JAXRSService {
     SAML2Request createLoginRequest(
             @QueryParam("spEntityID") String spEntityID,
             @QueryParam("urlContext") String urlContext,
-            @QueryParam("idpEntityID") String idpEntityID);
+            @QueryParam("idpEntityID") String idpEntityID,
+            @DefaultValue("false") @QueryParam("reauth") boolean reauth);
 
     /**
      * Validates the received SAML 2.0 authentication response and creates JWT for the matching user, if found.
diff --git a/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java b/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java
index 703272ba54..69f39b0b00 100644
--- a/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java
+++ b/ext/saml2sp4ui/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SP4UIServiceImpl.java
@@ -49,12 +49,13 @@ public class SAML2SP4UIServiceImpl extends AbstractService implements SAML2SP4UI
 
     @Override
     public SAML2Request createLoginRequest(
-            final String spEntityID, final String urlContext, final String idpEntityID) {
+            final String spEntityID, final String urlContext, final String idpEntityID, final boolean reauth) {
 
         return logic.createLoginRequest(
                 StringUtils.appendIfMissing(spEntityID, "/"),
                 urlContext,
-                idpEntityID);
+                idpEntityID,
+                reauth);
     }
 
     @Override