From 7dec314ed0a6d58948d22ae28b432815f7d0b949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Barto=C5=A1?= Date: Wed, 5 Feb 2020 17:01:36 +0100 Subject: [PATCH] KEYCLOAK-12900 NullPointerException during WebAuthn Registration (#6732) --- .../src/main/java/org/keycloak/WebAuthnConstants.java | 1 + .../authenticators/browser/WebAuthnAuthenticator.java | 11 +++++++---- .../requiredactions/WebAuthnRegister.java | 9 ++++++--- .../resources/theme/base/login/webauthn-error.ftl | 8 +++----- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/services/src/main/java/org/keycloak/WebAuthnConstants.java b/services/src/main/java/org/keycloak/WebAuthnConstants.java index 865c6975fc..d0ac2da721 100644 --- a/services/src/main/java/org/keycloak/WebAuthnConstants.java +++ b/services/src/main/java/org/keycloak/WebAuthnConstants.java @@ -44,6 +44,7 @@ public interface WebAuthnConstants { final String ALLOWED_AUTHENTICATORS = "authenticators"; final String IS_USER_IDENTIFIED = "isUserIdentified"; final String USER_VERIFICATION = "userVerification"; + final String IS_SET_RETRY = "isSetRetry"; // Event key for credential id generated by navigator.credentials.create() diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/browser/WebAuthnAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/browser/WebAuthnAuthenticator.java index 9b03916c1b..006eaa61c2 100644 --- a/services/src/main/java/org/keycloak/authentication/authenticators/browser/WebAuthnAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/browser/WebAuthnAuthenticator.java @@ -61,7 +61,6 @@ public class WebAuthnAuthenticator implements Authenticator, CredentialValidator private static final Logger logger = Logger.getLogger(WebAuthnAuthenticator.class); private KeycloakSession session; - private WebAuthnAuthenticatorsBean authenticators; public WebAuthnAuthenticator(KeycloakSession session) { this.session = session; @@ -84,7 +83,7 @@ public class WebAuthnAuthenticator implements Authenticator, CredentialValidator boolean isUserIdentified = false; if (user != null) { // in 2 Factor Scenario where the user has already been identified - authenticators = new WebAuthnAuthenticatorsBean(context.getSession(), context.getRealm(), user, getCredentialType()); + WebAuthnAuthenticatorsBean authenticators = new WebAuthnAuthenticatorsBean(context.getSession(), context.getRealm(), user, getCredentialType()); if (authenticators.getAuthenticators().isEmpty()) { // require the user to register webauthn authenticator return; @@ -287,8 +286,12 @@ public class WebAuthnAuthenticator implements Authenticator, CredentialValidator private Response createErrorResponse(AuthenticationFlowContext context, final String errorCase) { LoginFormsProvider provider = context.form().setError(errorCase); - if (authenticators != null && authenticators.getAuthenticators() != null) { - provider.setAttribute(WebAuthnConstants.ALLOWED_AUTHENTICATORS, authenticators); + UserModel user = context.getUser(); + if (user != null) { + WebAuthnAuthenticatorsBean authenticators = new WebAuthnAuthenticatorsBean(context.getSession(), context.getRealm(), user, getCredentialType()); + if (authenticators.getAuthenticators() != null) { + provider.setAttribute(WebAuthnConstants.ALLOWED_AUTHENTICATORS, authenticators); + } } return provider.createWebAuthnErrorPage(); } diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java b/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java index bba5a35dab..ebeaeff604 100644 --- a/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java +++ b/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java @@ -165,6 +165,12 @@ public class WebAuthnRegister implements RequiredActionProvider, CredentialRegis MultivaluedMap params = context.getHttpRequest().getDecodedFormParameters(); + String isSetRetry = params.getFirst(WebAuthnConstants.IS_SET_RETRY); + if (isSetRetry != null && !isSetRetry.isEmpty()) { + requiredActionChallenge(context); + return; + } + context.getEvent().detail(Details.CREDENTIAL_TYPE, getCredentialType()); // receive error from navigator.credentials.create() @@ -329,7 +335,6 @@ public class WebAuthnRegister implements RequiredActionProvider, CredentialRegis private static final String ERR_LABEL = "web_authn_registration_error"; private static final String ERR_DETAIL_LABEL = "web_authn_registration_error_detail"; - private static final String REGISTRATION_ATTR = "webAuthnRegistration"; private void setErrorResponse(RequiredActionContext context, final String errorCase, final String errorMessage) { Response errorResponse = null; @@ -343,7 +348,6 @@ public class WebAuthnRegister implements RequiredActionProvider, CredentialRegis errorResponse = context.form() .setError(errorCase) .setAttribute(WEB_AUTHN_TITLE_ATTR, WEBAUTHN_REGISTER_TITLE) - .setAttribute(REGISTRATION_ATTR,true) .createWebAuthnErrorPage(); context.challenge(errorResponse); break; @@ -356,7 +360,6 @@ public class WebAuthnRegister implements RequiredActionProvider, CredentialRegis errorResponse = context.form() .setError(errorCase) .setAttribute(WEB_AUTHN_TITLE_ATTR, WEBAUTHN_REGISTER_TITLE) - .setAttribute(REGISTRATION_ATTR,true) .createWebAuthnErrorPage(); context.challenge(errorResponse); break; diff --git a/themes/src/main/resources/theme/base/login/webauthn-error.ftl b/themes/src/main/resources/theme/base/login/webauthn-error.ftl index d86dcdad79..0f377c450c 100644 --- a/themes/src/main/resources/theme/base/login/webauthn-error.ftl +++ b/themes/src/main/resources/theme/base/login/webauthn-error.ftl @@ -6,10 +6,7 @@