[java-idp-plugin-webauthn] branch main updated: Cleanup user.id in WebAuthn client
Phil Smart
philip.smart at jisc.ac.uk
Tue May 21 10:24:42 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=f8f8d5692a7020471d9ac49fd6f7096d2288acf2
The following commit(s) were added to refs/heads/main by this push:
new f8f8d56 Cleanup user.id in WebAuthn client
f8f8d56 is described below
commit f8f8d5692a7020471d9ac49fd6f7096d2288acf2
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Tue May 21 11:24:37 2024 +0100
Cleanup user.id in WebAuthn client
---
.../webauthn/client/WebAuthnAuthenticationClient.java | 1 -
.../authn/webauthn/context/BaseWebAuthnContext.java | 5 ++++-
.../webauthn/context/WebAuthnAuthenticationContext.java | 3 ++-
.../client/impl/YubicoWebAuthnAuthenticationClient.java | 5 -----
.../client/impl/YubicoWebauthnClientFactory.java | 2 +-
.../webauthn/impl/LookupRegisteredCredentials.java | 17 ++++++++++++++---
.../authn/webauthn/impl/ValidateWebAuthnAssertion.java | 5 ++---
7 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/WebAuthnAuthenticationClient.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/WebAuthnAuthenticationClient.java
index 54cd9c4..876cff7 100644
--- a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/WebAuthnAuthenticationClient.java
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/client/WebAuthnAuthenticationClient.java
@@ -74,7 +74,6 @@ public interface WebAuthnAuthenticationClient {
*
* @throws AssertionFailureException if the assertion is not valid
*/
- //TODO do we need a userId supplied here?
@Nonnull AssertionResult validateAuthenticatorAssertionResponse(@Nullable final String username,
@Nullable final byte[] userId,
@Nonnull final PublicKeyCredentialRequestOptions publicKeyCredentialRequestOptions,
diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/BaseWebAuthnContext.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/BaseWebAuthnContext.java
index 49195d6..f75779e 100644
--- a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/BaseWebAuthnContext.java
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/BaseWebAuthnContext.java
@@ -50,7 +50,10 @@ public class BaseWebAuthnContext extends BaseContext {
/** The challenge sent to the authenticator in both registration and authentication ceremonies.*/
@Nullable private byte[] serverChallenge;
- /** The user.id supplied to the authenticator during registration. Generated by the IdP.*/
+ /**
+ * The user.id supplied to the authenticator during registration. Generated by the IdP. Returned in assertion
+ * responses as a userHandle.
+ */
@Nullable private byte[] userId;
/** Does the authentication/registration require user verification? */
diff --git a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnAuthenticationContext.java b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnAuthenticationContext.java
index 6cd6832..9bbedfd 100644
--- a/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnAuthenticationContext.java
+++ b/webauthn-api/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/context/WebAuthnAuthenticationContext.java
@@ -30,7 +30,8 @@ public final class WebAuthnAuthenticationContext extends BaseWebAuthnContext {
/** An assertion response that is the result of an authentication.*/
@Nullable
- private PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> authenticatorAssertionResponse;
+ private
+ PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> authenticatorAssertionResponse;
/** The public key credential request options for authentication.*/
@Nullable private PublicKeyCredentialRequestOptions publicKeyCredentialRequestOptions;
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 4307585..ee18734 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
@@ -96,10 +96,6 @@ public class YubicoWebAuthnAuthenticationClient implements WebAuthnAuthenticatio
.challenge(new ByteArray(requestParams.getChallenge()))
.rpId(rp.getIdentity().getId())
.allowCredentials(Optional.ofNullable(requestParams.getAllowCredentials()))
-// .extensions(
-// startAssertionOptions
-// .getExtensions()
-// .merge(startAssertionOptions.getExtensions().toBuilder().appid(appId).build()))
.userVerification(requestParams.getUserVerificationRequirement())
.timeout(Optional.of(60000l))
.build();
@@ -163,7 +159,6 @@ public class YubicoWebAuthnAuthenticationClient implements WebAuthnAuthenticatio
final AssertionRequest requestAssertion = AssertionRequest.builder()
.publicKeyCredentialRequestOptions(publicKeyCredentialRequestOptions)
- //TODO userHandle will always be null here. Check this?
.userHandle(Optional.ofNullable(userId != null ? new ByteArray(userId) : null))
.username(Optional.ofNullable(username))
.build();
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 85b6c31..c1af8be 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
@@ -48,7 +48,7 @@ import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
/**
- * Spring factory beans for creating a {@link YubicoWebAuthnAuthenticationClient}.
+ * Spring factory bean for creating a {@link YubicoWebAuthnAuthenticationClient}.
*/
@ThreadSafe
public class YubicoWebauthnClientFactory extends AbstractInitializableComponent
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentials.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentials.java
index 4bfc777..1178b97 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentials.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentials.java
@@ -15,6 +15,7 @@
package net.shibboleth.idp.plugin.authn.webauthn.impl;
import java.util.Collection;
+import java.util.Optional;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
@@ -24,6 +25,8 @@ import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
+import com.yubico.webauthn.data.ByteArray;
+
import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.plugin.authn.webauthn.authn.WebAuthnAuthenticationEventIds;
import net.shibboleth.idp.plugin.authn.webauthn.context.BaseWebAuthnContext;
@@ -35,12 +38,13 @@ import net.shibboleth.shared.primitive.LoggerFactory;
/**
* An action that lookups existing registered credentials based on the username contained in the WebAuthn context
- * and sets them back onto the context. If no credentials exist and the trigger event condition is set, an error
- * event will be produced.
+ * and sets them back onto the context. Also sets the user.id from the userHandle associated with the username.
+ * If no credentials exist and the trigger event condition is set, an error event will be produced.
*
* @event {@link AuthnEventIds#INVALID_AUTHN_CTX}
* @post BaseWebAuthnContext.setExistingCredentials() is either null if no existing credentials are found, or contains
- * the credentials from the credential repository
+ * the credentials from the credential repository. {@link BaseWebAuthnContext#getUserId()} != null if the userHandle is
+ * found from the username.
*/
public class LookupRegisteredCredentials extends AbstractWebAuthnBaseAction {
@@ -112,6 +116,13 @@ public class LookupRegisteredCredentials extends AbstractWebAuthnBaseAction {
log.debug("{} Found '{}' registered credentials for '{}'", getLogPrefix(), credentials.size(), username);
context.setExistingCredentials(credentials);
+ final Optional<ByteArray> userHandle = getCredentialRepository().getUserHandleForUsername(username);
+ if (userHandle.isPresent()) {
+ final byte[] userId = userHandle.get().getBytes();
+ assert userId != null;
+ context.setUserId(userId);
+ }
+
if (triggerEventOnNoCredentialsPredicate.test(profileRequestContext) && credentials.isEmpty()) {
log.debug("{} Triggering event '{}' ", getLogPrefix(), noCredentialsEventId);
ActionSupport.buildEvent(profileRequestContext, noCredentialsEventId);
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 6ac925d..54e0c7b 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
@@ -35,7 +35,7 @@ import net.shibboleth.shared.primitive.LoggerFactory;
/**
* An action that validates a WebAuthn Authenticator Assertion that results from a call to WebAuthn's 'get'
* (authentication) API. If successful, populates the Subject with a {@link UsernamePrincipal} based on the username in
- * the authentication context.
+ * the authentication context and a {@link WebAuthnUserIdPrinicpal} based on the user.id in the authentication context.
*
* @event {@link AuthnEventIds#INVALID_CREDENTIALS}
* @event {@link AuthnEventIds#INVALID_AUTHN_CTX}
@@ -130,11 +130,10 @@ public class ValidateWebAuthnAssertion extends AbstractValidationAction {
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> assertion =
context.getAuthenticatorAssertionResponse();
- // TODO username can be null in a usernameless flow
if (assertion == null) {
log.warn("{} No authenticator assertion found, {} can not authenticate",
getLogPrefix(),context.getUsername());
- handleError(profileRequestContext, authenticationContext, "InvalidResponseType",
+ handleError(profileRequestContext, authenticationContext, AuthnEventIds.INVALID_CREDENTIALS,
AuthnEventIds.INVALID_CREDENTIALS);
recordFailure(profileRequestContext);
return;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list