[java-idp-plugin-webauthn] branch main updated: Simplify credential to remove extraction actions

Phil Smart philip.smart at jisc.ac.uk
Wed Jun 5 11:19:23 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=9919b9b1250548d6c0fe71572a4f98ccab4682ee

The following commit(s) were added to refs/heads/main by this push:
     new 9919b9b  Simplify credential to remove extraction actions
9919b9b is described below

commit 9919b9b1250548d6c0fe71572a4f98ccab4682ee
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Jun 5 12:19:21 2024 +0100

    Simplify credential to remove extraction actions
---
 .../admin/WebAuthnRegistrationEventIds.java        |   6 ++
 .../context/WebAuthnManagementContext.java         |   2 +-
 ...xtractKeyRemovalInformationFromFormRequest.java | 105 ---------------------
 ...xtractKeyRemovalInformationFromFormRequest.java |  63 +++++++++----
 ...licKeyCredentialAttestationFromFormRequest.java |   6 +-
 ...ManagementContextCredentialRemovalConsumer.java |  77 +++++++++++++++
 .../impl/PopulateWebAuthnRegistrationContext.java  |   1 -
 ...gistrationContextCredentialRemovalConsumer.java |  77 +++++++++++++++
 ...ublicKeyCredentialAssertionFromFormRequest.java |   3 +-
 .../webauthn-management-beans.xml                  |  10 +-
 .../webauthn-registration-beans.xml                |   8 +-
 11 files changed, 221 insertions(+), 137 deletions(-)

diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/WebAuthnRegistrationEventIds.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/WebAuthnRegistrationEventIds.java
index e5dcb16..70d927d 100644
--- a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/WebAuthnRegistrationEventIds.java
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/WebAuthnRegistrationEventIds.java
@@ -38,5 +38,11 @@ public final class WebAuthnRegistrationEventIds {
     
     /** Management context is invalid. */
     @Nonnull @NotEmpty public static final String INVALID_MANAGEMENT_CTX = "InvalidManagmentContext";
+    
+    /** 
+     * A general event ID that is signalled if there is an issue performing an 'admin' action (e.g., registration or 
+     * user management). 
+     */
+    @Nonnull @NotEmpty public static final String INVALID_ADMIN_ACTION = "InvalidAdminAction";
 
 }
diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnManagementContext.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnManagementContext.java
index 7835c80..db442f5 100644
--- a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnManagementContext.java
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnManagementContext.java
@@ -31,7 +31,7 @@ import net.shibboleth.shared.collection.CollectionSupport;
  */
 public class WebAuthnManagementContext extends BaseContext {
     
-    /** Canonical principal name of subject. */
+    /** Canonical principal name of admin subject. */
     @Nullable private String principalName;  
     
     /** The username of the user to find and manage credentials for. */
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AdminExtractKeyRemovalInformationFromFormRequest.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AdminExtractKeyRemovalInformationFromFormRequest.java
deleted file mode 100644
index e7f15e8..0000000
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AdminExtractKeyRemovalInformationFromFormRequest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements.  See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID 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 net.shibboleth.idp.plugin.authn.webauthn.admin.impl;
-
-import javax.annotation.Nonnull;
-
-import org.opensaml.profile.action.ActionSupport;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.slf4j.Logger;
-
-import jakarta.servlet.http.HttpServletRequest;
-import net.shibboleth.idp.plugin.authn.webauthn.admin.WebAuthnRegistrationEventIds;
-import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnManagementContext;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.codec.Base64Support;
-import net.shibboleth.shared.codec.DecodingException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.primitive.StringSupport;
-
-
-/**
- * An action that extracts the credential ID for removal from the incoming HTTP request.
- * 
- * @event {AWebAuthnRegistrationEventIds#INVALID_REGISTRATION_CTX}
- * @event {EventIds#IO_ERROR}
- * @pre <pre>ProfileRequestContext.getSubcontext(WebAuthnManagementContext.class) != null</pre>
- * @post add credential ID to remove from the the management context
- */
-//TODO this is identical other than the context to ExtractKeyRemovalInformationFromFormRequest, we should only need one
-public class AdminExtractKeyRemovalInformationFromFormRequest extends AbstractWebAuthnManagementAction {
-
-    /** Default credential Id parameter name. */
-    @Nonnull @NotEmpty public static final String DEFAULT_PARAMETER_NAME = "credentialId";
-    
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(AdminExtractKeyRemovalInformationFromFormRequest.class);
-    
-    /** Name of credential Id parameter. */
-    @NonnullAfterInit @NotEmpty private String credentialIdParameterName;
-
-    /** Constructor. */
-    public AdminExtractKeyRemovalInformationFromFormRequest() {       
-        credentialIdParameterName = DEFAULT_PARAMETER_NAME;
-    }
-    
-    /**
-     * Set the name of the credential Id parameter.
-     * 
-     * @param field field name
-     */
-    public void setCedentialIdParameterName(@Nonnull @NotEmpty final String field) {
-        checkSetterPreconditions();
-        
-        credentialIdParameterName = Constraint.isNotNull(StringSupport.trimOrNull(field), "Credential ID "
-                + "parameter cannot be null or empty");
-    }
-    
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final WebAuthnManagementContext context) {
-        
-        final HttpServletRequest request = getHttpServletRequest();
-        if (request == null) {
-            log.debug("{} Profile action does not contain an HttpServletRequest", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, WebAuthnRegistrationEventIds.INVALID_REGISTRATION_CTX);
-            return;
-        }
-
-        final String credentialId = request.getParameter(credentialIdParameterName);         
-        if (credentialId == null) {
-            log.debug("{} CredentialID not found in HTTP request",getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext,  WebAuthnRegistrationEventIds.INVALID_REGISTRATION_CTX);
-            return;
-        }           
-        try {
-            // Should be base64 encoded credential.
-            final byte[] credentialIdAsBytes = Base64Support.decode(credentialId);
-            context.setCredentialIdToRemove(credentialIdAsBytes); 
-            log.trace("{} Credential to remove '{}'",getLogPrefix(),credentialId);
-        } catch (final DecodingException e) {
-            log.debug("{} Unable to base64 decode credentialID, can not remove credential", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, WebAuthnRegistrationEventIds.INVALID_REGISTRATION_CTX);
-            return;
-        }
-
-    }
-    
-}
\ No newline at end of file
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractKeyRemovalInformationFromFormRequest.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractKeyRemovalInformationFromFormRequest.java
index bb93d80..d2db154 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractKeyRemovalInformationFromFormRequest.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractKeyRemovalInformationFromFormRequest.java
@@ -17,33 +17,37 @@
 
 package net.shibboleth.idp.plugin.authn.webauthn.admin.impl;
 
+import java.util.function.BiConsumer;
+
 import javax.annotation.Nonnull;
 
 import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 
 import jakarta.servlet.http.HttpServletRequest;
-import net.shibboleth.idp.authn.AuthnEventIds;
-import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext;
+import net.shibboleth.idp.plugin.authn.webauthn.admin.WebAuthnRegistrationEventIds;
+import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.codec.Base64Support;
 import net.shibboleth.shared.codec.DecodingException;
+import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 
 
 /**
- * An action that extracts the credential identifier of the credential to remove from the incoming HTTP request.
+ * An action that extracts the credential ID for removal from the incoming HTTP request and uses a {@link BiConsumer}
+ * to set that back onto an appropriate context.
  * 
- * @event {AuthnEventIds#NO_CREDENTIALS}
- * @event {EventIds#IO_ERROR}
- * @pre <pre>ProfileRequestContext.getSubcontext(WebAuthnRegistrationContext.class) != null</pre>
- * @post add the credential identifier to the registration context
+ * @event {WebAuthnRegistrationEventIds#INVALID_ADMIN_ACTION}
+ * @event {EventIds#INVALID_PROFILE_CTX}
+ * @post add credential ID to remove to the context
  */
-public class ExtractKeyRemovalInformationFromFormRequest extends AbstractWebAuthnRegistrationAction {
+public class ExtractKeyRemovalInformationFromFormRequest extends AbstractProfileAction {
 
     /** Default credential Id parameter name. */
     @Nonnull @NotEmpty public static final String DEFAULT_PARAMETER_NAME = "credentialId";
@@ -52,50 +56,69 @@ public class ExtractKeyRemovalInformationFromFormRequest extends AbstractWebAuth
     @Nonnull private final Logger log = LoggerFactory.getLogger(ExtractKeyRemovalInformationFromFormRequest.class);
     
     /** Name of credential Id parameter. */
-    @NonnullAfterInit @NotEmpty private String credentialIdParameterName;
+    @Nonnull @NotEmpty private String credentialIdParameterName;
+    
+    @NonnullAfterInit private BiConsumer<ProfileRequestContext, byte[]> contextSettingConsumer;
 
     /** Constructor. */
     public ExtractKeyRemovalInformationFromFormRequest() {       
         credentialIdParameterName = DEFAULT_PARAMETER_NAME;
     }
     
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+        
+        if (contextSettingConsumer == null) {
+            throw new ComponentInitializationException("ContextSettingConsumer can not be null");
+        }
+    }
+    
+    /**
+     * @param consumer The contextSettingConsumer to set.
+     */
+    public void setContextSettingConsumer(final BiConsumer<ProfileRequestContext, byte[]> consumer) {
+        checkSetterPreconditions();
+        contextSettingConsumer = Constraint.isNotNull(consumer, "ContextSettingConsumer can not be null");
+    }
+    
     /**
      * Set the name of the credential Id parameter.
      * 
-     * @param parameter parameter name
+     * @param field field name
      */
-    public void setCredentialIdParameterName(@Nonnull @NotEmpty final String parameter) {
+    public void setCedentialIdParameterName(@Nonnull @NotEmpty final String field) {
         checkSetterPreconditions();
         
-        credentialIdParameterName = Constraint.isNotNull(StringSupport.trimOrNull(parameter), "Credential ID "
+        credentialIdParameterName = Constraint.isNotNull(StringSupport.trimOrNull(field), "Credential ID "
                 + "parameter cannot be null or empty");
     }
     
     @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
-            @Nonnull final WebAuthnRegistrationContext context) {
+    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         
         final HttpServletRequest request = getHttpServletRequest();
         if (request == null) {
             log.debug("{} Profile action does not contain an HttpServletRequest", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
             return;
         }
 
         final String credentialId = request.getParameter(credentialIdParameterName);         
         if (credentialId == null) {
-            log.debug("{} Credential ID not found in HTTP request",getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext,  AuthnEventIds.NO_CREDENTIALS);
+            log.debug("{} CredentialID not found in HTTP request",getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext,  WebAuthnRegistrationEventIds.INVALID_ADMIN_ACTION);
             return;
         }           
         try {
-            // Should be a base64 encoded credential.
+            // Should be base64 encoded credential.
             final byte[] credentialIdAsBytes = Base64Support.decode(credentialId);
-            context.setCredentialIdToRemove(credentialIdAsBytes); 
+            contextSettingConsumer.accept(profileRequestContext, credentialIdAsBytes);
             log.trace("{} Credential to remove '{}'",getLogPrefix(),credentialId);
         } catch (final DecodingException e) {
             log.debug("{} Unable to base64 decode credentialID, can not remove credential", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
+            ActionSupport.buildEvent(profileRequestContext, WebAuthnRegistrationEventIds.INVALID_ADMIN_ACTION);
             return;
         }
 
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractPublicKeyCredentialAttestationFromFormRequest.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractPublicKeyCredentialAttestationFromFormRequest.java
index fd9c692..0bfe579 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractPublicKeyCredentialAttestationFromFormRequest.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ExtractPublicKeyCredentialAttestationFromFormRequest.java
@@ -50,8 +50,8 @@ import net.shibboleth.shared.primitive.StringSupport;
  */
 public class ExtractPublicKeyCredentialAttestationFromFormRequest extends AbstractWebAuthnRegistrationAction {
 
-    /** Default public key credential assertion parameter name. */
-    @Nonnull @NotEmpty public static final String DEFAULT_PK_ASSERTION_FIELD_NAME = "publicKeyCredential";
+    /** Default public key credential attestation parameter name. */
+    @Nonnull @NotEmpty public static final String DEFAULT_PARAMETER_NAME = "publicKeyCredential";
     
     /** Default nickname parameter name. */
     @Nonnull @NotEmpty public static final String DEFAULT_NICKNAME_FIELD_NAME = "credentialNickname";
@@ -68,7 +68,7 @@ public class ExtractPublicKeyCredentialAttestationFromFormRequest extends Abstra
     
     /** Constructor. */
     public ExtractPublicKeyCredentialAttestationFromFormRequest() {
-        publicKeyCredentialAttestationParameterName = DEFAULT_PK_ASSERTION_FIELD_NAME;
+        publicKeyCredentialAttestationParameterName = DEFAULT_PARAMETER_NAME;
         credentialNicknameParameterName = DEFAULT_NICKNAME_FIELD_NAME;
     }
     
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ManagementContextCredentialRemovalConsumer.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ManagementContextCredentialRemovalConsumer.java
new file mode 100644
index 0000000..a973697
--- /dev/null
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/ManagementContextCredentialRemovalConsumer.java
@@ -0,0 +1,77 @@
+/*
+ * 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.function.BiConsumer;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnManagementContext;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * A {@link BiConsumer} that sets the credential ID to remove onto the WebAuthn management context.
+ */
+public class ManagementContextCredentialRemovalConsumer extends AbstractIdentifiableInitializableComponent 
+    implements BiConsumer<ProfileRequestContext, byte[]> {
+        
+    /** Class logger. */
+    @Nonnull @NotEmpty private final Logger log = LoggerFactory.getLogger(ManagementContextCredentialRemovalConsumer.class);
+    
+    /** Lookup strategy to locate the webauthn management context. */
+    @Nonnull 
+    private Function<ProfileRequestContext,WebAuthnManagementContext> webauthnManagementContextLookupStrategy;
+    
+    /** Constructor.*/
+    protected ManagementContextCredentialRemovalConsumer() {
+        //prc -> WebAuthnContext
+        webauthnManagementContextLookupStrategy = new ChildContextLookup<>(WebAuthnManagementContext.class);
+    }
+    
+    /**
+     * Set WebAuthn management context lookup strategy to use.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setWebauthnManagementContextLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,WebAuthnManagementContext> strategy) {
+        checkSetterPreconditions();
+
+        webauthnManagementContextLookupStrategy = 
+                Constraint.isNotNull(strategy, "WebauthnManagementContextLookupStrategy strategy cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void accept(final ProfileRequestContext prc, final byte[] credentialId) {
+        final WebAuthnManagementContext webauthnManagementContext = 
+                webauthnManagementContextLookupStrategy.apply(prc);
+        if (webauthnManagementContext == null) {
+            log.warn("{} No WebAuthn management context returned by lookup strategy, can not set credential "
+                    + "identifier to remove",getId()); 
+            return;
+        } 
+        webauthnManagementContext.setCredentialIdToRemove(credentialId);        
+    }
+
+}
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/PopulateWebAuthnRegistrationContext.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/PopulateWebAuthnRegistrationContext.java
index 1f491b5..4a0ce83 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/PopulateWebAuthnRegistrationContext.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/PopulateWebAuthnRegistrationContext.java
@@ -41,7 +41,6 @@ import net.shibboleth.shared.primitive.LoggerFactory;
  * @event {@link org.opensaml.profile.action.EventIds#INVALID_PROFILE_CTX}
  * @post a {@link WebAuthnRegistrationContext} is created and the username is populated.
  */
-//TODO The population actions are similar, can they be generalised?
 public class PopulateWebAuthnRegistrationContext extends AbstractProfileAction {
     
     /** Class logger. */
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/RegistrationContextCredentialRemovalConsumer.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/RegistrationContextCredentialRemovalConsumer.java
new file mode 100644
index 0000000..3187b2e
--- /dev/null
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/RegistrationContextCredentialRemovalConsumer.java
@@ -0,0 +1,77 @@
+/*
+ * 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.function.BiConsumer;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * A {@link BiConsumer} that sets the credential ID to remove onto the WebAuthn registration context.
+ */
+public class RegistrationContextCredentialRemovalConsumer extends AbstractIdentifiableInitializableComponent 
+    implements BiConsumer<ProfileRequestContext, byte[]> {
+        
+    /** Class logger. */
+    @Nonnull @NotEmpty private final Logger log = LoggerFactory.getLogger(RegistrationContextCredentialRemovalConsumer.class);
+    
+    /** Lookup strategy to locate the webauthn registration context. */
+    @Nonnull 
+    private Function<ProfileRequestContext,WebAuthnRegistrationContext> webauthnRegistrationContextLookupStrategy;
+    
+    /** Constructor.*/
+    protected RegistrationContextCredentialRemovalConsumer() {
+        //prc -> WebAuthnContext
+        webauthnRegistrationContextLookupStrategy = new ChildContextLookup<>(WebAuthnRegistrationContext.class);
+    }
+    
+    /**
+     * Set WebAuthn registration context lookup strategy to use.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setWebauthnRegistrationContextLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,WebAuthnRegistrationContext> strategy) {
+        checkSetterPreconditions();
+
+        webauthnRegistrationContextLookupStrategy = 
+                Constraint.isNotNull(strategy, "WebauthnContextLookuplookup strategy cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void accept(final ProfileRequestContext prc, final byte[] credentialId) {
+        final WebAuthnRegistrationContext webauthnRegistrationContext = 
+                webauthnRegistrationContextLookupStrategy.apply(prc);
+        if (webauthnRegistrationContext == null) {
+            log.warn("{} No WebAuthn registration context returned by lookup strategy, can not set credential "
+                    + "identifier to remove",getId()); 
+            return;
+        } 
+        webauthnRegistrationContext.setCredentialIdToRemove(credentialId);        
+    }
+
+}
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ExtractPublicKeyCredentialAssertionFromFormRequest.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ExtractPublicKeyCredentialAssertionFromFormRequest.java
index 974d686..6333e31 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ExtractPublicKeyCredentialAssertionFromFormRequest.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ExtractPublicKeyCredentialAssertionFromFormRequest.java
@@ -50,10 +50,9 @@ import net.shibboleth.shared.primitive.StringSupport;
  * @pre <pre>ProfileRequestContext.getSubcontext(WebAuthnAuthenticationContext.class) != null</pre>
  * @post <pre>WebAuthnAuthenticationContext.getAuthenticatorAssertionResponse() == null</pre>
  */
-//TODO similar to ExtractPublicKeyCredentialAttestationFromFormRequest
 public class ExtractPublicKeyCredentialAssertionFromFormRequest extends AbstractWebAuthnAuthenticationAction {
 
-    /** Default public key assertion parameter name. */
+    /** Default public key credential assertion parameter name. */
     @Nonnull @NotEmpty public static final String DEFAULT_PARAMETER_NAME = "publicKeyCredential";
     
     /** Class logger. */
diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-management/webauthn-management-beans.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-management/webauthn-management-beans.xml
index 84c3fd5..c0d6969 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-management/webauthn-management-beans.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-management/webauthn-management-beans.xml
@@ -46,9 +46,13 @@
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.LookupCredentialsForUser"
         p:webauthnManagementContextLookupStrategy-ref="shibboleth.ChildLookup.WebAuthnManagementContext" />
         
-    <bean id="ExtractKeyRemovalInformationFromFormRequest" parent="AbstractWebAuthnManagementAction" scope="prototype"
-        class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.AdminExtractKeyRemovalInformationFromFormRequest"
-        p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier" />
+    <bean id="ExtractKeyRemovalInformationFromFormRequest" scope="prototype"
+        class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.ExtractKeyRemovalInformationFromFormRequest"
+        p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier">
+        <property name="contextSettingConsumer">
+            <bean class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.ManagementContextCredentialRemovalConsumer"/>
+        </property>
+    </bean>
         
     <bean id="DeletePublicKeyCredential" parent="AbstractWebAuthnManagementAction" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.AdminDeletePublicKeyCredential" />
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 afd3504..2e91dbb 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
@@ -110,9 +110,13 @@
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.ExtractPublicKeyCredentialAttestationFromFormRequest"
         p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier" />
 
-    <bean id="ExtractKeyRemovalInformationFromFormRequest" parent="AbstractWebAuthnRegistrationAction" scope="prototype"
+    <bean id="ExtractKeyRemovalInformationFromFormRequest" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.ExtractKeyRemovalInformationFromFormRequest"
-        p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier" />
+        p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier">
+        <property name="contextSettingConsumer">
+            <bean class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.RegistrationContextCredentialRemovalConsumer"/>
+        </property> 
+     </bean>
 
     <bean id="DeletePublicKeyCredential" parent="AbstractWebAuthnRegistrationAction" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.DeletePublicKeyCredential" />

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


More information about the commits mailing list