WebAuthN - Failed to register your Security key (https)

Hello,

Im trying to get keycloak setup on a server on Azure, with WebAuthN.
I am using Keycloak 9.0.2

Ive managed to follow the documentation and successfully configure WebAuthN when running the server locally, but im having some trouble when I try and get it working with Azure.

Firstly, im on a VPN to my Azure network, with all ports open so i dont think its a firewall issue.

I created a self signed SSL certificate and successfully installed it onto the KeyCloak server as per the documentation. Ive updated my hosts file so the host matches the server and the certificate name. Ive configured the WebAuthN exactly as i did with the localhost deployment, except this time ive added keycloak_server as my Relying ID in the “WebAuthn Passwordless Policy” for the realm im trying to access.

When i register a new user, im prompted to touch the Yubikey 5 (without the relying ID it dosent get that far) and it seems that the request back to keycloak looks ok.

However the response back is pretty empty and looks completly different to the succesful localhost deployment. And obviously, its not working because i get the “Failed toregister your security key” message.

I dont actually get an errror, just a warning.

12:06:10,150 WARN  [org.keycloak.events] (default task-16) type=CUSTOM_REQUIRED_ACTION_ERROR, realmId=community1, clientId=account, userId=fc0862cc-b490-40dc-947a-789e6bb6d7fa, ipAddress=172.16.0.6, error=invalid_registration, credential_type=webauthn-passwordless, auth_method=openid-connect, custom_required_action=webauthn-register-passwordless, response_type=code, web_authn_registration_error=webauthn-error-registration, redirect_uri=https://keycloak_server:8443/auth/realms/community1/account/login-redirect, remember_me=false, code_id=c26cbf93-8097-4d1f-abae-aa95aa739033, response_mode=query, username=test12222, authSessionParentId=c26cbf93-8097-4d1f-abae-aa95aa739033, authSessionTabId=ZunQ5JG-TJs

I enabled debug and i see a bit more, im not very good with Java so am trying to avoid debugging in the code. My naive interpretation of the logs is that the keycloak server cant verify the origin sent back from the authenticator?

2020-04-03 06:46:21,484 DEBUG [io.undertow.request] (default I/O-4) Matched prefix path /auth for path /auth/realms/community1/login-actions/required-action
2020-04-03 06:46:21,485 DEBUG [io.undertow.request.security] (default task-24) Attempting to authenticate /auth/realms/community1/login-actions/required-action, authentication required: false
2020-04-03 06:46:21,485 DEBUG [io.undertow.request.security] (default task-24) Authentication outcome was NOT_ATTEMPTED with method io.undertow.security.impl.CachedAuthenticatedSessionMechanism@3012cdd6 for /auth/realms/community1/login-actions/required-action
2020-04-03 06:46:21,486 DEBUG [io.undertow.request.security] (default task-24) Authentication result was ATTEMPTED for /auth/realms/community1/login-actions/required-action
2020-04-03 06:46:21,486 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (default task-24) new JtaTransactionWrapper
2020-04-03 06:46:21,486 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (default task-24) was existing? false
2020-04-03 06:46:21,487 DEBUG [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-24) RESTEASY002315: PathInfo: /realms/community1/login-actions/required-action
2020-04-03 06:46:21,488 DEBUG [org.keycloak.services.resources.SessionCodeChecks] (default task-24) Will use client 'account' in back-to-application link
2020-04-03 06:46:21,488 DEBUG [org.keycloak.services.util.CookieHelper] (default task-24) {1} cookie found in the requests header
2020-04-03 06:46:21,488 DEBUG [org.keycloak.services.util.CookieHelper] (default task-24) {1} cookie found in the cookies field
2020-04-03 06:46:21,488 DEBUG [org.keycloak.services.managers.AuthenticationSessionManager] (default task-24) Found AUTH_SESSION_ID cookie with value e6f1f111-f5f7-4d40-9228-c9565246aa71.keycloak_server
2020-04-03 06:46:21,548 DEBUG [org.keycloak.authentication.requiredactions.WebAuthnRegister] (default task-24) null: java.lang.NullPointerException
        at com.webauthn4j.data.client.Origin.equals(Origin.java:137)
        at java.util.Objects.equals(Objects.java:59)
        at com.webauthn4j.validator.OriginValidator.validate(OriginValidator.java:43)
        at com.webauthn4j.validator.RegistrationDataValidator.validate(RegistrationDataValidator.java:131)
        at com.webauthn4j.WebAuthnManager.validate(WebAuthnManager.java:211)
        at org.keycloak.authentication.requiredactions.WebAuthnRegister.processAction(WebAuthnRegister.java:216)
        at org.keycloak.services.resources.LoginActionsService.processRequireAction(LoginActionsService.java:1025)
        at org.keycloak.services.resources.LoginActionsService.requiredActionPOST(LoginActionsService.java:960)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138)
        at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:517)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:406)
        at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:370)
        at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:356)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:372)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:344)
        at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137)
        at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135)
        at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:356)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215)
        at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227)
        at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
        at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
        at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
        at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:91)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
        at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
        at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
        at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
        at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
        at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
        at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
        at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
        at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
        at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
        at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
        at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
        at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
        at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
        at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
        at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
        at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
        at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
        at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)
        at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
        at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
        at java.lang.Thread.run(Thread.java:748)

2020-04-03 06:46:21,548 WARN  [org.keycloak.authentication.requiredactions.WebAuthnRegister] (default task-24) webauthn-error-registration
2020-04-03 06:46:21,549 WARN  [org.keycloak.events] (default task-24) type=CUSTOM_REQUIRED_ACTION_ERROR, realmId=community1, clientId=account, userId=4240c98c-9e6a-47cf-88c1-5b87f8aad983, ipAddress=172.16.0.6, error=invalid_registration, credential_type=webauthn-passwordless, auth_method=openid-connect, custom_required_action=webauthn-register-passwordless, response_type=code, web_authn_registration_error=webauthn-error-registration, redirect_uri=https://keycloak_server:8443/auth/realms/community1/account/login-redirect, remember_me=false, code_id=e6f1f111-f5f7-4d40-9228-c9565246aa71, response_mode=query, username=test, authSessionParentId=e6f1f111-f5f7-4d40-9228-c9565246aa71, authSessionTabId=6ANG232QkZo
2020-04-03 06:46:21,549 DEBUG [freemarker.cache] (default task-24) Couldn't find template in cache for "webauthn-error.ftl"("en", UTF-8, parsed); will try to load it.
2020-04-03 06:46:21,549 DEBUG [freemarker.cache] (default task-24) TemplateLoader.findTemplateSource("webauthn-error_en.ftl"): Not found
2020-04-03 06:46:21,549 DEBUG [freemarker.cache] (default task-24) TemplateLoader.findTemplateSource("webauthn-error.ftl"): Found
2020-04-03 06:46:21,549 DEBUG [freemarker.cache] (default task-24) Loading template for "webauthn-error.ftl"("en", UTF-8, parsed) from "file:/keycloak/themes/base/login/webauthn-error.ftl"
2020-04-03 06:46:21,551 DEBUG [freemarker.cache] (default task-24) Couldn't find template in cache for "template.ftl"("en", UTF-8, parsed); will try to load it.
2020-04-03 06:46:21,551 DEBUG [freemarker.cache] (default task-24) TemplateLoader.findTemplateSource("template_en.ftl"): Not found
2020-04-03 06:46:21,551 DEBUG [freemarker.cache] (default task-24) TemplateLoader.findTemplateSource("template.ftl"): Found
2020-04-03 06:46:21,551 DEBUG [freemarker.cache] (default task-24) Loading template for "template.ftl"("en", UTF-8, parsed) from "file:/keycloak/themes/base/login/template.ftl"
2020-04-03 06:46:21,558 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (default task-24) JtaTransactionWrapper  commit
2020-04-03 06:46:21,558 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (default task-24) JtaTransactionWrapper end

The keycloak server itself can resolve “keycloak_server”. Ive tweaked the settings a fair bit but still cant get anywhere.

I tried changing the attestation to “none” in the hopes it would not do checking, but it still fails with the same message.

Any help would be greatly appreciated.
Thanks,
Ashley

I figured it out! It was really silly actually.

My server is called keycloak-server but for some reason i decided to make my hosts file entry reference keycloak_server. Having an underscore in your hostname is invalid.
I removed the custom relying party id under webauth passwordless settings and left it empty. I ensured that my host files referenced keycloak-server and i was in business.

Shame that keycloak/webauthnj didnt give a more useful output.