[java-idp-plugin-webauthn] branch main updated: JWEBAUTHN-16 - Add auditing

Phil Smart philip.smart at jisc.ac.uk
Tue Jul 2 11:31:10 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=764c7314c5df526e0d9606b20de9a9ae507a84a6

The following commit(s) were added to refs/heads/main by this push:
     new 764c731  JWEBAUTHN-16 - Add auditing
764c731 is described below

commit 764c7314c5df526e0d9606b20de9a9ae507a84a6
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Tue Jul 2 12:31:06 2024 +0100

    JWEBAUTHN-16 - Add auditing
    
     - Add authn flow auditing.
    
    https://shibboleth.atlassian.net/browse/JWEBAUTHN-16
---
 .../audit/AbstractWebAuthnAuditExtractor.java      | 70 +++++++++++++++++++++
 .../authn/webauthn/audit/WebAuthnAuditFields.java  | 40 ++++++++++++
 webauthn-impl/pom.xml                              | 10 ++-
 .../audit/impl/WebAuthnFlowModeAuditExtractor.java | 59 ++++++++++++++++++
 .../audit/impl/WebAuthnUserIdAuditExtractor.java   | 57 +++++++++++++++++
 .../WebAuthnUserVerificationAuditExtractor.java    | 71 ++++++++++++++++++++++
 .../audit/impl/WebAuthnUsernameAuditExtractor.java | 47 ++++++++++++++
 .../webauthn/impl/AbstractWebAuthnBaseAction.java  |  1 -
 .../webauthn/impl/ValidateWebAuthnAssertion.java   |  5 +-
 .../idp/flows/authn/WebAuthn/webauthn-beans.xml    | 51 +++++++++++++++-
 10 files changed, 404 insertions(+), 7 deletions(-)

diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/AbstractWebAuthnAuditExtractor.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/AbstractWebAuthnAuditExtractor.java
new file mode 100644
index 0000000..d2ba8c5
--- /dev/null
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/AbstractWebAuthnAuditExtractor.java
@@ -0,0 +1,70 @@
+/*
+ * 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.audit;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.authn.webauthn.context.BaseWebAuthnContext;
+import net.shibboleth.shared.logic.Constraint;
+
+/** 
+ * An abstract audit extractor function to extract values directly from various WebAuthn contexts.
+ * 
+ * @param <T> the type to extract
+ */
+ at ThreadSafe
+public abstract class AbstractWebAuthnAuditExtractor<T> implements Function<ProfileRequestContext, T> {
+    
+    /** Lookup strategy to locate the WebAuthn base context. */
+    @Nonnull 
+    private final Function<ProfileRequestContext,BaseWebAuthnContext> webAuthnBaseContextLookupStrategy;
+    
+    /** Constructor.*/
+    protected AbstractWebAuthnAuditExtractor(
+            @Nonnull final Function<ProfileRequestContext,BaseWebAuthnContext> strategy) {
+        webAuthnBaseContextLookupStrategy = Constraint.isNotNull(strategy, 
+                "BaseWebAuthnContext lookup strategy can not be null");
+    }
+    
+    
+    @Override
+    @Nullable public T apply(@Nullable final ProfileRequestContext profileRequestContext) {
+        
+        if (profileRequestContext == null) {
+            return null;
+        }
+        final BaseWebAuthnContext webAuthnContext = webAuthnBaseContextLookupStrategy.apply(profileRequestContext);
+        if (webAuthnContext == null) {
+            return null;
+        } 
+        return doLookup(webAuthnContext);
+    }
+    
+    /**
+     * Implemented to perform the actual lookup.
+     * 
+     * @param context the base WebAuthn context
+     * 
+     * @return lookup value or {@code null} if not found
+     */
+    @Nullable protected abstract T doLookup(@Nonnull final BaseWebAuthnContext context);
+
+}
diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/WebAuthnAuditFields.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/WebAuthnAuditFields.java
new file mode 100644
index 0000000..79de0e4
--- /dev/null
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/WebAuthnAuditFields.java
@@ -0,0 +1,40 @@
+/*
+ * 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.audit;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+
+/**
+ * Audit fields for WebAuthn
+ */
+public final class WebAuthnAuditFields {
+    
+    /** Private constructor.*/
+    private WebAuthnAuditFields() {
+        
+    }
+    
+    /** The user.id of the currently authenticated user. */
+    @Nonnull @NotEmpty public static final String USERID = "WebAuthnUID";
+    
+    /** Was the currently authenticated user verified (UserVerification). */
+    @Nonnull @NotEmpty public static final String UV = "WebAuthnUV";
+    
+    /** What mode produced the final result e.g. 'passwordless'. */
+    @Nonnull @NotEmpty public static final String FLOW_MODE = "WebAuthnFM";
+
+}
diff --git a/webauthn-impl/pom.xml b/webauthn-impl/pom.xml
index c429101..e361d1d 100644
--- a/webauthn-impl/pom.xml
+++ b/webauthn-impl/pom.xml
@@ -62,7 +62,7 @@
             <artifactId>numbers</artifactId>
             <scope>runtime</scope>
         </dependency>
-        <!-- Service API and Plugin Description dependencies -->
+        <!-- Provided dependencies -->
         <dependency>
             <groupId>${spring-webflow.groupId}</groupId>
             <artifactId>spring-webflow</artifactId>
@@ -102,8 +102,7 @@
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
             <scope>provided</scope>
-        </dependency>
-        <!-- Provided dependencies -->
+        </dependency>        
         <dependency>
             <groupId>net.shibboleth</groupId>
             <artifactId>shib-security</artifactId>          
@@ -114,6 +113,11 @@
             <artifactId>idp-authn-api</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>${idp.groupId}</groupId>
+            <artifactId>idp-authn-impl</artifactId>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>${shib-shared.groupId}</groupId>
             <artifactId>shib-support</artifactId>
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnFlowModeAuditExtractor.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnFlowModeAuditExtractor.java
new file mode 100644
index 0000000..900c3f7
--- /dev/null
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnFlowModeAuditExtractor.java
@@ -0,0 +1,59 @@
+/*
+ * 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.audit.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.authn.webauthn.audit.AbstractWebAuthnAuditExtractor;
+import net.shibboleth.idp.plugin.authn.webauthn.context.BaseWebAuthnContext;
+import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnAuthenticationContext;
+
+/**
+ * {@link Function} that returns which mode of flow was run e.g. 'passwordless', 'usernameless', or 'second-factor'.
+ */
+public class WebAuthnFlowModeAuditExtractor extends AbstractWebAuthnAuditExtractor<String> {    
+
+    /**
+     * Constructor.
+     *
+     * @param strategy the {@link BaseWebAuthnContext} lookup strategy to use.
+     */
+    protected WebAuthnFlowModeAuditExtractor(
+            @Nonnull final Function<ProfileRequestContext, BaseWebAuthnContext> strategy) {
+        super(strategy);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String doLookup(@Nonnull final BaseWebAuthnContext context) {
+        
+        if (context instanceof final WebAuthnAuthenticationContext authnContext) {
+            if (authnContext.isPasswordless()) {
+                return "passwordless";
+            } else if (authnContext.isUsernameless()) {
+                return "usernameless";
+            } else if (authnContext.isSecondFactor()) {
+                return "second-factor";
+            }
+        }
+        return null;
+
+    }
+    
+}
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUserIdAuditExtractor.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUserIdAuditExtractor.java
new file mode 100644
index 0000000..780e244
--- /dev/null
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUserIdAuditExtractor.java
@@ -0,0 +1,57 @@
+/*
+ * 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.audit.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.authn.webauthn.audit.AbstractWebAuthnAuditExtractor;
+import net.shibboleth.idp.plugin.authn.webauthn.context.BaseWebAuthnContext;
+import net.shibboleth.shared.codec.Base64Support;
+import net.shibboleth.shared.codec.EncodingException;
+
+/**
+ * {@link Function} that returns the user.id from the {@link BaseWebAuthnContext} base64 encoded, if any.
+ */
+public class WebAuthnUserIdAuditExtractor extends AbstractWebAuthnAuditExtractor<String> {    
+
+    /**
+     * Constructor.
+     *
+     * @param strategy the {@link BaseWebAuthnContext} lookup strategy to use.
+     */
+    protected WebAuthnUserIdAuditExtractor(
+            @Nonnull final Function<ProfileRequestContext, BaseWebAuthnContext> strategy) {
+        super(strategy);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String doLookup(@Nonnull final BaseWebAuthnContext context) {
+        final byte[] userId = context.getUserId();
+        if (userId == null) {
+            return null;
+        }
+        try {
+            return Base64Support.encodeURLSafe(userId);
+        } catch (final EncodingException e) {
+            return null;
+        }
+    }
+    
+}
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUserVerificationAuditExtractor.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUserVerificationAuditExtractor.java
new file mode 100644
index 0000000..519ab02
--- /dev/null
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUserVerificationAuditExtractor.java
@@ -0,0 +1,71 @@
+/*
+ * 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.audit.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.yubico.webauthn.data.AuthenticatorAssertionResponse;
+import com.yubico.webauthn.data.ClientAssertionExtensionOutputs;
+import com.yubico.webauthn.data.PublicKeyCredential;
+
+import net.shibboleth.idp.plugin.authn.webauthn.audit.AbstractWebAuthnAuditExtractor;
+import net.shibboleth.idp.plugin.authn.webauthn.context.BaseWebAuthnContext;
+import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnAuthenticationContext;
+
+/**
+ * {@link Function} that returns true if UserVerification was performed, false otherwise. 
+ */
+public class WebAuthnUserVerificationAuditExtractor extends AbstractWebAuthnAuditExtractor<String> {    
+
+    /**
+     * Constructor.
+     *
+     * @param strategy the {@link BaseWebAuthnContext} lookup strategy to use.
+     */
+    protected WebAuthnUserVerificationAuditExtractor(
+            @Nonnull final Function<ProfileRequestContext, BaseWebAuthnContext> strategy) {
+        super(strategy);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String doLookup(@Nonnull final BaseWebAuthnContext context) {
+        
+        if (context instanceof final WebAuthnAuthenticationContext authnContext) {
+            final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> response = 
+                    authnContext.getPublicKeyCredentialAssertionResponse();
+            if (response != null) {
+                final var authenticatorResponse = response.getResponse();
+                if (authenticatorResponse != null) {
+                    final var authnData = authenticatorResponse.getParsedAuthenticatorData();
+                    if (authnData != null) {
+                        if (authnData.getFlags().UV) {
+                            return "true";
+                        } else {
+                            return "false";
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+
+    }
+    
+}
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUsernameAuditExtractor.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUsernameAuditExtractor.java
new file mode 100644
index 0000000..4abdece
--- /dev/null
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/audit/impl/WebAuthnUsernameAuditExtractor.java
@@ -0,0 +1,47 @@
+/*
+ * 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.audit.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.authn.webauthn.audit.AbstractWebAuthnAuditExtractor;
+import net.shibboleth.idp.plugin.authn.webauthn.context.BaseWebAuthnContext;
+
+/**
+ * {@link Function} that returns the username from the {@link BaseWebAuthnContext}, if any.
+ */
+public class WebAuthnUsernameAuditExtractor extends AbstractWebAuthnAuditExtractor<String> {    
+
+    /**
+     * Constructor.
+     *
+     * @param strategy the {@link BaseWebAuthnContext} lookup strategy to use.
+     */
+    protected WebAuthnUsernameAuditExtractor(
+            @Nonnull final Function<ProfileRequestContext, BaseWebAuthnContext> strategy) {
+        super(strategy);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String doLookup(@Nonnull final BaseWebAuthnContext context) {
+        return context.getUsername();
+    }
+    
+}
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnBaseAction.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnBaseAction.java
index 0bed813..34d30a7 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnBaseAction.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnBaseAction.java
@@ -64,7 +64,6 @@ public abstract class AbstractWebAuthnBaseAction extends BaseWebAuthnAction {
     
     /** Constructor.*/
     protected AbstractWebAuthnBaseAction() {
-        //prc -> WebAuthnBaseContext
         webAuthnBaseContextLookupStrategy = new ChildContextLookup<>(BaseWebAuthnContext.class).
                 compose(new ChildContextLookup<>(AuthenticationContext.class));
     }
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertion.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertion.java
index 2356d0d..82991ff 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertion.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertion.java
@@ -17,9 +17,9 @@ import com.yubico.webauthn.data.ClientAssertionExtensionOutputs;
 import com.yubico.webauthn.data.PublicKeyCredential;
 import com.yubico.webauthn.data.PublicKeyCredentialRequestOptions;
 
-import net.shibboleth.idp.authn.AbstractValidationAction;
 import net.shibboleth.idp.authn.AuthnEventIds;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.impl.AbstractAuditingValidationAction;
 import net.shibboleth.idp.authn.principal.UsernamePrincipal;
 import net.shibboleth.idp.plugin.authn.webauthn.authn.AssertionResult;
 import net.shibboleth.idp.plugin.authn.webauthn.client.WebAuthnAuthenticationClient;
@@ -42,7 +42,7 @@ import net.shibboleth.shared.primitive.LoggerFactory;
  * @event {@link AuthnEventIds#INVALID_CREDENTIALS}
  * @event {@link AuthnEventIds#INVALID_AUTHN_CTX}
  */
-public class ValidateWebAuthnAssertion extends AbstractValidationAction {
+public class ValidateWebAuthnAssertion extends AbstractAuditingValidationAction {
     
     /** Class logger. */
     @Nonnull
@@ -194,6 +194,7 @@ public class ValidateWebAuthnAssertion extends AbstractValidationAction {
             context.setUsername(result.getUsername());
             context.setUserId(result.getUserId());
             buildAuthenticationResult(profileRequestContext, authenticationContext);
+            recordSuccess(profileRequestContext);
             
         } catch (final AssertionFailureException e) {
             log.warn("{} Error validating authenticator assertion for '{}'", 
diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-beans.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-beans.xml
index bb624f7..3ffcd13 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-beans.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-beans.xml
@@ -123,7 +123,56 @@
         class="net.shibboleth.idp.plugin.authn.webauthn.impl.ValidateWebAuthnAssertion"
         p:webAuthnClient="#{getObject('shibboleth.authn.webauthn.DefaultWebAuthnAuthenticationClientFactory')}" 
         p:credentialRepository-ref="shibboleth.authn.webauthn.DefaultCredentialRepository"
-        p:updateSignatureCountPredicate="#{getObject('shibboleth.authn.webauthn.UpdateSignatureCountPredicate') ?: %{idp.authn.webauthn.updateSignatureCount:true}}"/>
+        p:updateSignatureCountPredicate="#{getObject('shibboleth.authn.webauthn.UpdateSignatureCountPredicate') ?: %{idp.authn.webauthn.updateSignatureCount:true}}"
+        p:populateAuditContextAction="#{%{idp.authn.webauthn.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('shibboleth.authn.webauthn.PopulateAuditContext') : null}"
+        p:writeAuditLogAction="#{%{idp.authn.webauthn.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('WriteAuthnAuditLog') : null}"/>
 
+    <!-- Audit logging beans. -->
+
+    <!-- Default audit format and extractors --> 
+    <util:map id="shibboleth.authn.AuditFormattingMap">
+        <entry key="#{'%{idp.authn.webauthn.audit.category:Shibboleth-Audit.WebAuthn}'.trim()}"
+            value="#{'%{idp.authn.webauthn.audit.format:%a|%T|%SP|%I|%s|%AF|%CV|%u|%WebAuthnUID|%WebAuthnUV|%WebAuthnFM|%tu|%AR|%UA}'.trim()}" />
+    </util:map>
+    
+    <bean id="shibboleth.authn.webauthn.PopulateAuditContext" parent="shibboleth.authn.AbstractPopulateAuditContext" lazy-init="true"
+        p:fieldExtractors="#{getObject('shibboleth.authn.webauthn.AuditExtractors') ?: getObject('shibboleth.authn.webauthn.DefaultAuditExtractors')}"
+        p:clearAuditContext="true" />
+        
+    <bean id="shibboleth.authn.webauthn.DefaultAuditExtractors" parent="shibboleth.authn.DefaultAuditExtractors" lazy-init="true"
+            class="org.springframework.beans.factory.config.MapFactoryBean">
+        <property name="sourceMap">
+             <map merge="true">
+               <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.idp.profile.IdPAuditFields.USERNAME"/>
+                    </key>
+                    <bean class="net.shibboleth.idp.plugin.authn.webauthn.audit.impl.WebAuthnUsernameAuditExtractor" 
+                        c:_0-ref="shibboleth.ChildLookup.WebAuthnAuthenticationContextFromAuthenticationContext"/>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.idp.plugin.authn.webauthn.audit.WebAuthnAuditFields.USERID"/>
+                    </key>
+                    <bean class="net.shibboleth.idp.plugin.authn.webauthn.audit.impl.WebAuthnUserIdAuditExtractor" 
+                        c:_0-ref="shibboleth.ChildLookup.WebAuthnAuthenticationContextFromAuthenticationContext"/>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.idp.plugin.authn.webauthn.audit.WebAuthnAuditFields.UV"/>
+                    </key>
+                    <bean class="net.shibboleth.idp.plugin.authn.webauthn.audit.impl.WebAuthnUserVerificationAuditExtractor" 
+                        c:_0-ref="shibboleth.ChildLookup.WebAuthnAuthenticationContextFromAuthenticationContext"/>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.idp.plugin.authn.webauthn.audit.WebAuthnAuditFields.FLOW_MODE"/>
+                    </key>
+                    <bean class="net.shibboleth.idp.plugin.authn.webauthn.audit.impl.WebAuthnFlowModeAuditExtractor" 
+                        c:_0-ref="shibboleth.ChildLookup.WebAuthnAuthenticationContextFromAuthenticationContext"/>
+                </entry>
+             </map>
+        </property>
+    </bean>
 
 </beans>

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


More information about the commits mailing list