[java-idp-plugin-webauthn] branch main updated: Add Attestation Conveyance Preference to options

Phil Smart philip.smart at jisc.ac.uk
Mon Feb 5 18:39:05 UTC 2024


This is an automated email from the git hooks/post-receive script.

philsmart pushed a commit to branch main
in repository java-idp-plugin-webauthn.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-webauthn.git;a=commit;h=8a0dca01a13ff1cdbb3c228ba1b4fc5683ad77b3

The following commit(s) were added to refs/heads/main by this push:
     new 8a0dca0  Add Attestation Conveyance Preference to options
8a0dca0 is described below

commit 8a0dca01a13ff1cdbb3c228ba1b4fc5683ad77b3
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Mon Feb 5 18:39:02 2024 +0000

    Add Attestation Conveyance Preference to options
    
     - Does not yet store the attestation if returned
---
 .../admin/CredentialCreationOptionsParameters.java | 48 +++++++++++--
 .../context/WebAuthnRegistrationContext.java       | 29 +++++++-
 .../impl/AddAttestationConveyancePreference.java   | 78 ++++++++++++++++++++++
 .../CreatePublicKeyCredentialCreationOptions.java  | 11 ++-
 .../impl/YubicoWebauthnAuthenticationClient.java   |  1 +
 .../client/impl/YubicoWebauthnClientFactory.java   | 37 +++++-----
 .../webauthn-registration-beans.xml                |  4 ++
 .../webauthn-registration-flow.xml                 |  1 +
 .../authn/webauthn/conf/authn/webauthn.properties  |  5 +-
 .../authn/webauthn/views/webauthn-registered.vm    |  2 +-
 10 files changed, 187 insertions(+), 29 deletions(-)

diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/CredentialCreationOptionsParameters.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/CredentialCreationOptionsParameters.java
index 0e1a7ae..f2ace6e 100644
--- a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/CredentialCreationOptionsParameters.java
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/CredentialCreationOptionsParameters.java
@@ -20,6 +20,7 @@ import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import com.yubico.webauthn.data.AttestationConveyancePreference;
 import com.yubico.webauthn.data.AuthenticatorAttachment;
 import com.yubico.webauthn.data.PublicKeyCredentialDescriptor;
 import com.yubico.webauthn.data.ResidentKeyRequirement;
@@ -53,7 +54,10 @@ public class CredentialCreationOptionsParameters extends BaseOptionsParameters {
     @Nonnull final ResidentKeyRequirement residentKeyRequirement;    
     
     /** The userhandle supplied to the authenticator during registration. As generated by the IdP.*/
-    @Nonnull final byte[] userHandle;
+    @Nonnull final byte[] userHandle;    
+    
+    /** The Attestation conveyance preference.*/
+    @Nonnull private final AttestationConveyancePreference attestationConveyancePreference;
 
     /**
      * 
@@ -71,6 +75,8 @@ public class CredentialCreationOptionsParameters extends BaseOptionsParameters {
                 "Resident key requirement can not be null");
         this.userHandle = Constraint.isNotNull(builder.userHandle, "UserHandle can not be null");
         this.authenticatorAttachment = builder.authenticatorAttachment;
+        this.attestationConveyancePreference = Constraint.isNotNull(builder.attestationConveyancePreference, 
+                "AttestationConveyancePreference can not be null");
     }
 
     /**
@@ -121,6 +127,15 @@ public class CredentialCreationOptionsParameters extends BaseOptionsParameters {
     @Nonnull public final byte[] getUserHandle() {
         return userHandle;
     }
+    
+    /**
+     * Get the attestation conveyance preference.
+     * 
+     * @return the attestation conveyance preference.
+     */
+    public AttestationConveyancePreference getAttestationConveyancePreference() {
+        return attestationConveyancePreference;
+    }
 
 
     /**
@@ -204,7 +219,20 @@ public class CredentialCreationOptionsParameters extends BaseOptionsParameters {
          * @param userHandle the user handle
          * @return the next stage
          */
-        public IBuildStage withUserHandle(@Nonnull final byte[] userHandle);
+        public IAttestationConveyancePreferenceStage withUserHandle(@Nonnull final byte[] userHandle);
+    }
+    
+    
+    /** Stage interface.*/
+    public interface IAttestationConveyancePreferenceStage {
+        /**
+         * The attestation conveyance preference.
+         * 
+         * @param preference the preference
+         * @return the next stage
+         */
+        public IBuildStage withAttestationConveyancePreference(
+                @Nonnull final AttestationConveyancePreference preference);
     }
 
 
@@ -230,7 +258,8 @@ public class CredentialCreationOptionsParameters extends BaseOptionsParameters {
 
     /** Builder class.*/
     public static final class Builder implements IUserVerificationRequirementStage, IChallengeStage,
-            IExcludeCredentialsStage, IUsernameStage, IResidentKeyRequirementStage, IUserHandleStage, IBuildStage {
+            IExcludeCredentialsStage, IUsernameStage, IResidentKeyRequirementStage, IUserHandleStage, 
+            IAttestationConveyancePreferenceStage, IBuildStage {
         
         /** Does the authentication/registration require user verification.*/
         private UserVerificationRequirement userVerificationRequirement;
@@ -252,6 +281,9 @@ public class CredentialCreationOptionsParameters extends BaseOptionsParameters {
         
         /** The AuthenticatorAttachment requirement. {@code null} would represent either possibility.*/
         private AuthenticatorAttachment authenticatorAttachment;
+        
+        /** The Attestation conveyance preference.*/
+        private AttestationConveyancePreference attestationConveyancePreference;
 
         /** Constructor.*/
         private Builder() {
@@ -291,10 +323,18 @@ public class CredentialCreationOptionsParameters extends BaseOptionsParameters {
         }
 
         @Override
-        public IBuildStage withUserHandle(@Nonnull final byte[] userHandle) {
+        public IAttestationConveyancePreferenceStage withUserHandle(@Nonnull final byte[] userHandle) {
             this.userHandle = userHandle;
             return this;
         }
+        
+        
+        @Override
+        public IBuildStage withAttestationConveyancePreference(
+                @Nonnull final AttestationConveyancePreference preference) {
+            attestationConveyancePreference = preference;
+            return this;
+        }
 
         @Override
         public IBuildStage withAuthenticatorAttachment(
diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnRegistrationContext.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnRegistrationContext.java
index dccbb42..78aefef 100644
--- a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnRegistrationContext.java
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnRegistrationContext.java
@@ -5,6 +5,7 @@ import javax.annotation.Nullable;
 import javax.annotation.concurrent.NotThreadSafe;
 
 import com.yubico.webauthn.RegistrationResult;
+import com.yubico.webauthn.data.AttestationConveyancePreference;
 import com.yubico.webauthn.data.AuthenticatorAttachment;
 import com.yubico.webauthn.data.AuthenticatorAttestationResponse;
 import com.yubico.webauthn.data.ClientRegistrationExtensionOutputs;
@@ -57,7 +58,10 @@ public final class WebAuthnRegistrationContext extends BaseWebAuthnContext {
     @Nullable private ResidentKeyRequirement residentKeyRequirement;
     
     /** The AuthenticatorAttachment requirement. {@code null} would represent either possibility.*/
-    @Nullable private AuthenticatorAttachment authenticatorAttachmentRequirement;
+    @Nullable private AuthenticatorAttachment authenticatorAttachmentRequirement;    
+
+    /** The attestation preference.*/
+    @Nullable private AttestationConveyancePreference attestationConveyancePreference;
     
     /**
      * Set the AuthenticatorAttachment requirement. {@code null} would represent either possibility.
@@ -237,4 +241,27 @@ public final class WebAuthnRegistrationContext extends BaseWebAuthnContext {
     @Nullable public ResidentKeyRequirement getResidentKeyRequirement() {
         return residentKeyRequirement;
     }
+    
+
+    /**
+     * Set the attestation conveyance preference.
+     * 
+     * @param preference the attestation conveyance preference
+     * 
+     * @return this context
+     */
+    @Nonnull public BaseWebAuthnContext setAttestationConveyancePreference(
+            @Nullable final AttestationConveyancePreference preference) {
+        attestationConveyancePreference = preference;
+        return this;        
+    }
+    
+    /**
+     * Get the attestation conveyance preference.
+     *  
+     * @return the attestationConveyancePreference.
+     */
+    @Nullable public AttestationConveyancePreference getAttestationConveyancePreference() {
+        return attestationConveyancePreference;
+    }
 }
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAttestationConveyancePreference.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAttestationConveyancePreference.java
new file mode 100644
index 0000000..ac585bd
--- /dev/null
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAttestationConveyancePreference.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed 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 net.shibboleth.idp.plugin.authn.webauthn.admin.impl;
+
+import java.util.stream.Stream;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import com.yubico.webauthn.data.AttestationConveyancePreference;
+
+import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnAuthenticationContext;
+import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Add a Attestation Preference to the {@link WebAuthnAuthenticationContext context}.
+ */
+public class AddAttestationConveyancePreference extends AbstractWebAuthnRegistrationAction {
+    
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AddAttestationConveyancePreference.class);
+    
+    /** The attestation conveyance preference. Default is 'none'. */
+    @Nonnull private AttestationConveyancePreference attestationConveyancePreference;
+    
+    /** Constructor.*/
+    public AddAttestationConveyancePreference() {
+        attestationConveyancePreference = AttestationConveyancePreference.NONE;
+    }
+    
+    /**
+     * Set the UserVerification requirement. 
+     * 
+     * @param requirement The userVerificationRequirement to set.
+     */
+    public void setAttestationConveyancePreference(@Nonnull @NotEmpty final String preference) {
+        checkSetterPreconditions();
+        Constraint.isNotEmpty(preference, "AttestationConveyancePreference can not be null or empty");
+        
+        final AttestationConveyancePreference attestationPreference = 
+                Stream.of(AttestationConveyancePreference.values())
+                .filter(uv -> uv.getValue().equals(preference))
+                .findAny()
+                .orElseThrow(() -> 
+                new ConstraintViolationException("Attestation conveyance preference '"+preference+"' unknown"));
+        assert attestationPreference != null;
+        attestationConveyancePreference = attestationPreference;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
+            @Nonnull final WebAuthnRegistrationContext context) {
+
+        log.debug("{} Attestation conveyance preference is '{}'",getLogPrefix(), attestationConveyancePreference);
+        context.setAttestationConveyancePreference(attestationConveyancePreference);
+        
+    }
+
+}
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java
index e08b9ee..6ca356f 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/CreatePublicKeyCredentialCreationOptions.java
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.yubico.webauthn.data.AttestationConveyancePreference;
 import com.yubico.webauthn.data.PublicKeyCredentialCreationOptions;
 import com.yubico.webauthn.data.PublicKeyCredentialDescriptor;
 import com.yubico.webauthn.data.ResidentKeyRequirement;
@@ -113,6 +114,12 @@ public class CreatePublicKeyCredentialCreationOptions extends AbstractWebAuthnRe
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
             return;
         }
+        final AttestationConveyancePreference attestationPreference = context.getAttestationConveyancePreference();
+        if (attestationPreference == null) {
+            log.error("{} AttestationConveyancePreference is null",getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+            return;
+        }
 
         try {       
             
@@ -130,7 +137,9 @@ public class CreatePublicKeyCredentialCreationOptions extends AbstractWebAuthnRe
                     .withExcludeCredentials(existingCredentialDescriptors)
                     .withUsername(username)
                     .withResidentKeyRequirement(residentKeyRequirement)
-                    .withUserHandle(userHandle).withAuthenticatorAttachment(
+                    .withUserHandle(userHandle)
+                    .withAttestationConveyancePreference(attestationPreference)
+                    .withAuthenticatorAttachment(
                             context.getAuthenticatorAttachmentRequirement())
                     .build();
 
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClient.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClient.java
index 25e0f61..3277c78 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClient.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClient.java
@@ -138,6 +138,7 @@ public class YubicoWebauthnAuthenticationClient implements WebAuthnAuthenticatio
                     .challenge(new ByteArray(creationOptions.getChallenge()))
                     .pubKeyCredParams(preferredPublickeyParams)
                     .excludeCredentials(creationOptions.getExcludeCredentials())
+                    .attestation(creationOptions.getAttestationConveyancePreference())
                     .authenticatorSelection(AuthenticatorSelectionCriteria.builder()
                             .userVerification(creationOptions.getUserVerificationRequirement())
                             .residentKey(creationOptions.getResidentKeyRequirement())
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnClientFactory.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnClientFactory.java
index 7685d01..f57fe1e 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnClientFactory.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnClientFactory.java
@@ -65,7 +65,10 @@ public class YubicoWebauthnClientFactory extends AbstractInitializableComponent
     /** The credential repository to store valid credentials in.*/
     @GuardedBy("this") @NonnullAfterInit private CredentialRepository credentialRepository;
     
-    /** Allowable origins for this Relying Party. Overrides the origin derived from the relyingPartyId if used.*/
+    /** 
+     * Allowable origins the authenticator response can contain. 
+     * Overrides an origin derived from the relyingPartyId if set.
+     */
     @GuardedBy("this") @Nonnull @NonnullElements private Set<String> origins;
     
     /** Constructor.*/
@@ -96,31 +99,23 @@ public class YubicoWebauthnClientFactory extends AbstractInitializableComponent
     @Override
     public WebAuthnAuthenticationClient getObject() throws Exception {
         
-        // FIXME: There is a bug in the builder here than prevents origins from being set as null
+        // FIXME: There is an issue in the builder here than prevents origins from being set as null
         // once that is fixed, we only need one builder statement here.
+        final var builder = RelyingParty.builder().identity(
+                RelyingPartyIdentity
+                .builder()
+                .id(getRelyingPartyId())
+                .name(getRelyingPartyName())
+                .build()).credentialRepository(getCredentialRepository())
+        .allowOriginPort(isAllowOriginPort())
+        .allowOriginSubdomain(isAllowOriginSubdomain());
+        
         if (!getOrigins().isEmpty()) {            
-            final RelyingParty rp = RelyingParty.builder().identity(
-                    RelyingPartyIdentity
-                    .builder()
-                    .id(getRelyingPartyId())
-                    .name(getRelyingPartyName())
-                    .build()).credentialRepository(getCredentialRepository())
-            .allowOriginPort(isAllowOriginPort())
-            .allowOriginSubdomain(isAllowOriginSubdomain())
-            .origins(getOrigins())
-            .build();
+            final RelyingParty rp = builder.origins(getOrigins()).build();
             assert rp != null;
             return new YubicoWebauthnAuthenticationClient(rp, getObjectMapper());
         } else {
-            final RelyingParty rp = RelyingParty.builder().identity(
-                    RelyingPartyIdentity
-                    .builder()
-                    .id(getRelyingPartyId())
-                    .name(getRelyingPartyName())
-                    .build()).credentialRepository(getCredentialRepository())
-            .allowOriginPort(isAllowOriginPort())
-            .allowOriginSubdomain(isAllowOriginSubdomain())
-            .build();
+            final RelyingParty rp = builder.build();
             assert rp != null;
             return new YubicoWebauthnAuthenticationClient(rp, getObjectMapper());
         }        
diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml
index 0933b6c..3b92309 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml
@@ -26,6 +26,10 @@
                 class="net.shibboleth.idp.plugin.authn.webauthn.impl.UsernameFromAuthenticationContextLookupStrategy" />
         </property>
     </bean>
+    
+    <bean id="AddAttestationConveyancePreference" scope="prototype" parent="AbstractWebAuthnRegistrationAction"
+        class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.AddAttestationConveyancePreference"
+        p:attestationConveyancePreference="%{idp.authn.webauthn.registration.attestationConveyancePreference:none}"/>
 
     <bean id="AddResidentKeyRequirement" scope="prototype" parent="AbstractWebAuthnRegistrationAction"
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.AddResidentKeyRequirement"
diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
index 2531e61..f8c01cf 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
@@ -30,6 +30,7 @@
         <evaluate expression="GenerateUserHandle"/>
         <evaluate expression="AddResidentKeyRequirement"/>
         <evaluate expression="AddAuthenticatorAttachmentRequirement"/>
+         <evaluate expression="AddAttestationConveyancePreference"/>
         <evaluate expression="AddUserVerificationRequired"/>
         <evaluate expression="CreatePublicKeyCredentialCreationOptions"/>
         <evaluate expression="'proceed'" />
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/conf/authn/webauthn.properties b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/conf/authn/webauthn.properties
index ae6f003..aadccd2 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/conf/authn/webauthn.properties
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/conf/authn/webauthn.properties
@@ -7,7 +7,7 @@ idp.authn.webauthn.relyingPartyName = Shibboleth
 idp.authn.webauthn.allowOriginPort = true
 ## Allow any subdomain of that origin
 idp.authn.webauthn.allowOriginSubdomain = false
-## An override of origins this RP is allowed to register and authenticate credentials for (must match that returned by the browser during registration or authentication)
+## An override of origins this RP allows in a response from an authenticator
 #idp.authn.webauthn.origins = https://localhost
 
 ## Which type of flow is supported? Usernameless or passwordless
@@ -20,6 +20,9 @@ idp.authn.webauthn.allowOriginSubdomain = false
 # idp.authn.webauthn.registration.authenticatorAttachment = any
 ### Require User Verification
 # idp.authn.webauthn.registration.userVerification = discouraged
+### State the preference of the IdP during registration to receive an authenticator attestation. One-of 'none', 
+### 'indirect', 'direct', or 'enterprise'.
+idp.authn.webauthn.registration.attestationConveyancePreference = direct
 
 ## Settings for allowing 2FA usage of the WebAuthn flow.
 idp.authn.webauthn.2fa.allowedPreviousFactors = authn/Password
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
index 60938f8..64067ee 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
@@ -59,7 +59,7 @@
                             <th>#springMessageText("idp.webauthn.register.table.keyName", "Key Name")</th>
                             <th>#springMessageText("idp.webauthn.register.table.transports", "Transports")</th>
                             <th>#springMessageText("idp.webauthn.register.table.passkey", "Passkey?")</th>
-                            <th>#springMessageText("idp.webauthn.register.table.userVerifiedOnRegistration", "User Verified On Registration")</th>
+                            <th>#springMessageText("idp.webauthn.register.table.userVerifiedOnRegistration", "User Verified?")</th>
                             <th>#springMessageText("idp.webauthn.register.table.registrationTime", "Registration Time")</th>
                         </tr>
                         #foreach($cred in $webauthnRegContext.existingCredentials)

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list