From c427e65354a208cedbfb828e47e6a631f903b384 Mon Sep 17 00:00:00 2001 From: mposolda Date: Mon, 18 Mar 2024 15:40:39 +0100 Subject: [PATCH] Secondary factor bypass in step-up authentication closes #34 Signed-off-by: mposolda (cherry picked from commit e632c03ec4dbfbb7c74c65b0627027390b2e605d) --- .../src/account-security/SigningIn.tsx | 62 ++-- js/apps/account-ui/src/api/methods.ts | 10 - js/apps/account-ui/src/index.ts | 1 - .../migration/migrators/MigrateTo24_0_3.java | 56 ++++ .../datastore/DefaultMigrationManager.java | 2 + .../AbstractAuthenticationFlowContext.java | 6 + .../AuthenticationFlowCallback.java | 6 +- .../authentication/CredentialAction.java | 37 +++ .../authentication/CredentialRegistrator.java | 5 +- .../RequiredActionProvider.java | 6 +- .../java/org/keycloak/events/Details.java | 1 + .../main/java/org/keycloak/events/Errors.java | 4 + .../java/org/keycloak/models/Constants.java | 2 + .../models/utils/DefaultRequiredActions.java | 14 + .../AuthenticationProcessor.java | 5 + .../authentication/AuthenticatorUtil.java | 38 +++ .../DefaultAuthenticationFlow.java | 2 +- .../browser/CookieAuthenticator.java | 9 +- .../ConditionalLoaAuthenticator.java | 16 +- .../authenticators/util/AcrStore.java | 82 +++++- .../authenticators/util/LoAUtil.java | 85 +++++- .../DeleteCredentialAction.java | 194 +++++++++++++ .../RecoveryAuthnCodesAction.java | 9 +- .../requiredactions/UpdateTotp.java | 6 + .../requiredactions/WebAuthnRegister.java | 6 + .../util/CredentialDeleteHelper.java | 111 ++++++++ .../keycloak/protocol/oidc/TokenManager.java | 2 +- .../oidc/endpoints/AuthorizationEndpoint.java | 12 +- .../protocol/oidc/utils/AcrUtils.java | 4 +- .../keycloak/services/messages/Messages.java | 1 + .../account/AccountCredentialResource.java | 70 +++-- ...cloak.authentication.RequiredActionFactory | 1 + .../CustomAuthenticationFlowCallback.java | 3 +- .../testsuite/account/AccountRestClient.java | 173 ++++++++++++ .../testsuite/pages/DeleteCredentialPage.java | 59 ++++ .../account/AccountRestServiceTest.java | 2 +- ...ppInitiatedActionDeleteCredentialTest.java | 267 ++++++++++++++++++ .../authentication/RequiredActionsTest.java | 1 + .../forms/LevelOfAssuranceFlowTest.java | 258 ++++++++++++++++- .../migration/AbstractMigrationTest.java | 14 + .../webauthn/utils/SigningInPageUtils.java | 18 +- .../account/AbstractWebAuthnAccountTest.java | 6 +- .../theme/base/login/delete-credential.ftl | 15 + .../login/messages/messages_en.properties | 4 + 44 files changed, 1545 insertions(+), 140 deletions(-) create mode 100644 model/storage-private/src/main/java/org/keycloak/migration/migrators/MigrateTo24_0_3.java create mode 100644 server-spi-private/src/main/java/org/keycloak/authentication/CredentialAction.java create mode 100644 services/src/main/java/org/keycloak/authentication/requiredactions/DeleteCredentialAction.java create mode 100644 services/src/main/java/org/keycloak/authentication/requiredactions/util/CredentialDeleteHelper.java create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/account/AccountRestClient.java create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/DeleteCredentialPage.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionDeleteCredentialTest.java create mode 100644 themes/src/main/resources/theme/base/login/delete-credential.ftl diff --git a/js/apps/account-ui/src/account-security/SigningIn.tsx b/js/apps/account-ui/src/account-security/SigningIn.tsx index 81a9ceba30..502521c240 100644 --- a/js/apps/account-ui/src/account-security/SigningIn.tsx +++ b/js/apps/account-ui/src/account-security/SigningIn.tsx @@ -19,12 +19,10 @@ import { } from "@patternfly/react-core/deprecated"; import { CSSProperties, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; -import { ContinueCancelModal, useAlerts } from "ui-shared"; -import { deleteCredentials, getCredentials } from "../api/methods"; +import { getCredentials } from "../api/methods"; import { CredentialContainer, CredentialMetadataRepresentation, - CredentialRepresentation, } from "../api/representations"; import { EmptyRow } from "../components/datalist/EmptyRow"; import { Page } from "../components/page/Page"; @@ -70,16 +68,15 @@ const MobileLink = ({ title, onClick, testid }: MobileLinkProps) => { export const SigningIn = () => { const { t } = useTranslation(); const context = useEnvironment(); - const { addAlert, addError } = useAlerts(); const { login } = context.keycloak; const [credentials, setCredentials] = useState(); - const [key, setKey] = useState(1); - const refresh = () => setKey(key + 1); - usePromise((signal) => getCredentials({ signal, context }), setCredentials, [ - key, - ]); + usePromise( + (signal) => getCredentials({ signal, context }), + setCredentials, + [], + ); const credentialRowCells = ( credMetadata: CredentialMetadataRepresentation, @@ -115,9 +112,6 @@ export const SigningIn = () => { return items; }; - const label = (credential: CredentialRepresentation) => - credential.userLabel || t(credential.type as TFuncKey); - if (!credentials) { return ; } @@ -205,41 +199,19 @@ export const SigningIn = () => { aria-labelledby={`cred-${meta.credential.id}`} > {container.removeable ? ( - { - try { - await deleteCredentials( - context, - meta.credential, - ); - addAlert( - t("successRemovedMessage", { - userLabel: label(meta.credential), - }), - ); - refresh(); - } catch (error) { - addError( - t("errorRemovedMessage", { - userLabel: label(meta.credential), - error, - }).toString(), - ); - } + ) : (