[java-idp-plugin-webauthn] branch main updated: Add more flow tests
Phil Smart
philip.smart at jisc.ac.uk
Thu Aug 8 16:08:44 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=766bdc84f9bed349da5848bc0958c55c32694f3e
The following commit(s) were added to refs/heads/main by this push:
new 766bdc8 Add more flow tests
766bdc8 is described below
commit 766bdc84f9bed349da5848bc0958c55c32694f3e
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Thu Aug 8 17:08:40 2024 +0100
Add more flow tests
---
.../impl/PopulateWebAuthnRegistrationContext.java | 1 -
.../YubicoWebauthnAuthenticationClientTest.java | 8 +-
.../webauthn/flow/AbstractWebAuthnFlowTest.java | 57 +++++++++-
.../authn/webauthn/flow/TestPasswordlessFlow.java | 2 +-
.../authn/webauthn/flow/TestSecondFactorFlow.java | 2 +-
.../authn/webauthn/flow/TestUsernameslessFlow.java | 117 ++++++++++++++++++++-
.../authn/webauthn/impl/AbstractWebAuthnTest.java | 2 +-
...kupRegisteredCredentialsFromUserHandleTest.java | 8 +-
.../impl/ValidateWebAuthnAssertionTest.java | 4 +-
.../webauthn/storage/impl/MockAuthenticator.java | 13 ++-
10 files changed, 187 insertions(+), 27 deletions(-)
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 a28c6ca..4e909cf 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
@@ -62,7 +62,6 @@ public class PopulateWebAuthnRegistrationContext extends AbstractProfileAction {
/** Constructor.*/
public PopulateWebAuthnRegistrationContext() {
// Default creates a WebAuthn registration context under the profile request context.
- //TODO does this makes sense directly under the PRC?
webAuthnRegistrationContextCreationStrategy =
new ChildContextLookup<>(WebAuthnRegistrationContext.class, true);
usernameRequiredPredicate = PredicateSupport.alwaysFalse();
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClientTest.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClientTest.java
index f621e00..933be35 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClientTest.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/client/impl/YubicoWebauthnAuthenticationClientTest.java
@@ -201,7 +201,7 @@ public class YubicoWebauthnAuthenticationClientTest extends AbstractWebAuthnTest
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
final AssertionResult result =
client.validateAuthenticatorAssertionResponse(USERNAME, Base64Support.decode(USER_HANDLE_B64),
@@ -249,7 +249,7 @@ public class YubicoWebauthnAuthenticationClientTest extends AbstractWebAuthnTest
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
client.validateAuthenticatorAssertionResponse(USERNAME, Base64Support.decode(USER_HANDLE_B64),
credentialRequestOptions, assertion);
@@ -294,7 +294,7 @@ public class YubicoWebauthnAuthenticationClientTest extends AbstractWebAuthnTest
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
client.validateAuthenticatorAssertionResponse(USERNAME, Base64Support.decode(USER_HANDLE_B64),
credentialRequestOptions, assertion);
@@ -340,7 +340,7 @@ public class YubicoWebauthnAuthenticationClientTest extends AbstractWebAuthnTest
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
client.validateAuthenticatorAssertionResponse(USERNAME, Base64Support.decode(USER_HANDLE_B64),
credentialRequestOptions, assertion);
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/AbstractWebAuthnFlowTest.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/AbstractWebAuthnFlowTest.java
index aae9c29..709abd1 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/AbstractWebAuthnFlowTest.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/AbstractWebAuthnFlowTest.java
@@ -374,7 +374,7 @@ public class AbstractWebAuthnFlowTest extends AbstractFlowTest {
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
return assertion;
}
@@ -382,21 +382,70 @@ public class AbstractWebAuthnFlowTest extends AbstractFlowTest {
/**
* Create a credential authentication assertion response from the mock authenticator.
*
+ * @param credentialId the credential ID to find the correct credential to sign the request with
+ * @param challenge the challenge to use
* @return the credential registration
*
* @throws Exception on error
*/
protected PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
- createAssertionReponseFromCredentialID(
+ createAssertionReponseFrom(
final byte[] credentialId, final byte[] challenge) throws Exception {
+ return createAssertionReponseFrom(credentialId, challenge, ORIGIN);
+ }
+
+ /**
+ * Create a credential authentication assertion response from the mock authenticator.
+ *
+ * @param credentialId the credential ID to find the correct credential to sign the request with
+ * @param challenge the challenge to use
+ * @param the origin to use
+ *
+ * @return the credential registration
+ *
+ * @throws Exception on error
+ */
+ protected PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
+ createAssertionReponseFrom(
+ final byte[] credentialId, final byte[] challenge, final String origin) throws Exception {
+
+ final String challengeB64 = Base64Support.encodeURLSafe(challenge);
+ final Map<String, String> clientDataGet = createClientData("webauthn.get", origin, challengeB64);
+
+ // Now generate an assertion (authentication) and check it is valid
+ final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
+ assertion = mockAuthenticator.createAuthenticatorAssertionResponse(credentialId,
+ clientDataGet, null);
+
+ return assertion;
+ }
+
+ /**
+ * Create a credential authentication assertion response from the mock authenticator.
+ *
+ * @param credentialId the credential ID to find the correct credential to sign the request with
+ * @param challenge the challenge to use
+ * @param the origin to use
+ * @param userHandle the userHandle to use in the assertion response (overrides the one that was stored in the
+ * attestation)
+ *
+ * @return the credential registration
+ *
+ * @throws Exception on error
+ */
+ protected PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
+ createAssertionReponseFrom(
+ final byte[] credentialId, final byte[] challenge, final String origin, final byte[] userHandle)
+ throws Exception {
+
final String challengeB64 = Base64Support.encodeURLSafe(challenge);
- final Map<String, String> clientDataGet = createClientData("webauthn.get", ORIGIN, challengeB64);
+ final Map<String, String> clientDataGet = createClientData("webauthn.get", origin, challengeB64);
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(credentialId,
- clientDataGet);
+ clientDataGet, userHandle);
return assertion;
}
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestPasswordlessFlow.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestPasswordlessFlow.java
index d841df0..aa46e0d 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestPasswordlessFlow.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestPasswordlessFlow.java
@@ -98,7 +98,7 @@ public class TestPasswordlessFlow extends AbstractWebAuthnFlowTest{
final ByteArray challenge = authnContext.getPublicKeyCredentialRequestOptions().getChallenge();
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
- assertionResponse = createAssertionReponseFromCredentialID(
+ assertionResponse = createAssertionReponseFrom(
registration.getCredential().getCredentialId().getBytes(), challenge.getBytes());
final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestSecondFactorFlow.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestSecondFactorFlow.java
index ee5e10f..de94724 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestSecondFactorFlow.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestSecondFactorFlow.java
@@ -91,7 +91,7 @@ public class TestSecondFactorFlow extends AbstractWebAuthnFlowTest{
final ByteArray challenge = authnContext.getPublicKeyCredentialRequestOptions().getChallenge();
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
- assertionResponse = createAssertionReponseFromCredentialID(
+ assertionResponse = createAssertionReponseFrom(
registration.getCredential().getCredentialId().getBytes(), challenge.getBytes());
final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestUsernameslessFlow.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestUsernameslessFlow.java
index 81fa5ec..c35ade3 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestUsernameslessFlow.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/flow/TestUsernameslessFlow.java
@@ -31,6 +31,7 @@ import com.yubico.webauthn.data.ByteArray;
import com.yubico.webauthn.data.ClientAssertionExtensionOutputs;
import com.yubico.webauthn.data.PublicKeyCredential;
+import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnAuthenticationContext;
import net.shibboleth.idp.plugin.authn.webauthn.impl.ExtractPublicKeyCredentialAssertionFromFormRequest;
import net.shibboleth.idp.plugin.authn.webauthn.storage.CredentialRegistration;
@@ -87,7 +88,7 @@ public class TestUsernameslessFlow extends AbstractWebAuthnFlowTest{
final ByteArray challenge = authnContext.getPublicKeyCredentialRequestOptions().getChallenge();
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
- assertionResponse = createAssertionReponseFromCredentialID(
+ assertionResponse = createAssertionReponseFrom(
registration.getCredential().getCredentialId().getBytes(), challenge.getBytes());
final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
@@ -106,6 +107,114 @@ public class TestUsernameslessFlow extends AbstractWebAuthnFlowTest{
}
+ @SuppressWarnings("null")
+ @Test
+ public void testUsernamelessFlow_WrongOrigin() throws Exception {
+
+ //Register a credential for use.
+ final CredentialRegistration registration =
+ createCredentialRegistration(USERNAME, DISPLAY_NAME, USER_HANDLE_B64);
+ credentialRepo.addRegistrationByUsername(USERNAME, registration);
+
+ final var prc = buildProfileRequestContext(false, false, null);
+
+ final Pair<FlowExecutionResult, FlowExecutionImpl> result = launchExecution(FLOW_ID, null, externalContext,
+ addToConversationScopeMap(Map.of("opensamlProfileRequestContext", prc)));
+
+ assertFlowExecutionActive(result.getSecond());
+ assertCurrentStateEquals("DisplayWebAuthnView", result.getSecond());
+ assertPublicKeyCredentialRequestOptions(prc, false, true);
+
+ // Do assertion validation half of flow
+
+ // Get the challenge that was set into the PublicKeyCredentialRequestOptions.
+ // otherwise we will end up signing a different one, which will provide its own test.
+ final WebAuthnAuthenticationContext authnContext = getWebAuthnAuthenticationContext(prc);
+ final ByteArray challenge = authnContext.getPublicKeyCredentialRequestOptions().getChallenge();
+
+ final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
+ assertionResponse = createAssertionReponseFrom(
+ registration.getCredential().getCredentialId().getBytes(), challenge.getBytes(), "wrong.origin.com");
+
+ final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
+
+ // Re-set external context to holder
+ ExternalContextHolder.setExternalContext(externalContext);
+ setHttpFormRequest("POST", Map.of(ExtractPublicKeyCredentialAssertionFromFormRequest.DEFAULT_PARAMETER_NAME,
+ assertionResponseJson));
+ externalContext.setEventId("proceed");
+ result.getSecond().setCurrentState("DisplayWebAuthnView");
+ result.getSecond().resume(externalContext);
+
+
+ assertEquals(result.getSecond().getOutcome().getId(), AuthnEventIds.INVALID_CREDENTIALS);
+ assertAuthenticationFailureConditions(prc);
+
+ }
+
+ /**
+ * Test a validation error that the user identified by the overriden assertion userHandle is not in possession of
+ * the credential used to sign the assertion response (as identified by the credentialID in the authenticator data
+ * in the response).
+ *
+ * @throws Exception
+ */
+ @SuppressWarnings("null")
+ @Test
+ public void testUsernamelessFlow_WrongUserHandleForUsername() throws Exception {
+
+ //Register a credential for use for the actual/real user.
+ final CredentialRegistration registration =
+ createCredentialRegistration(USERNAME, DISPLAY_NAME, USER_HANDLE_B64);
+ credentialRepo.addRegistrationByUsername(USERNAME, registration);
+
+ //Register a second users credential with different
+ final var userHandleSecondUserB64 = "2fixsNecxhORZpf4LMU9nA==";
+ final ByteArray userHandleBytesSecondUser = ByteArray.fromBase64(userHandleSecondUserB64);
+ final CredentialRegistration registrationTwo =
+ createCredentialRegistration("second-user", "second user", userHandleSecondUserB64);
+ credentialRepo.addRegistrationByUsername("second-user", registrationTwo);
+
+ final var prc = buildProfileRequestContext(false, false, null);
+
+ final Pair<FlowExecutionResult, FlowExecutionImpl> result = launchExecution(FLOW_ID, null, externalContext,
+ addToConversationScopeMap(Map.of("opensamlProfileRequestContext", prc)));
+
+ assertFlowExecutionActive(result.getSecond());
+ assertCurrentStateEquals("DisplayWebAuthnView", result.getSecond());
+ assertPublicKeyCredentialRequestOptions(prc, false, true);
+
+ // Do assertion validation half of flow
+
+ // Get the challenge that was set into the PublicKeyCredentialRequestOptions.
+ // otherwise we will end up signing a different one, which will provide its own test.
+ final WebAuthnAuthenticationContext authnContext = getWebAuthnAuthenticationContext(prc);
+ final ByteArray challenge = authnContext.getPublicKeyCredentialRequestOptions().getChallenge();
+
+ // Create an assertion response using the credential (and credentialID) from the real user, but using the
+ // second users userHandle. This should fail, as the userHandle does not link to a user with that credential
+ final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
+ assertionResponse = createAssertionReponseFrom(
+ registration.getCredential().getCredentialId().getBytes(), challenge.getBytes(), "wrong.origin.com",
+ userHandleBytesSecondUser.getBytes());
+
+ final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
+
+ // Re-set external context to holder
+ ExternalContextHolder.setExternalContext(externalContext);
+ setHttpFormRequest("POST", Map.of(ExtractPublicKeyCredentialAssertionFromFormRequest.DEFAULT_PARAMETER_NAME,
+ assertionResponseJson));
+ externalContext.setEventId("proceed");
+ result.getSecond().setCurrentState("DisplayWebAuthnView");
+ result.getSecond().resume(externalContext);
+
+
+ assertEquals(result.getSecond().getOutcome().getId(), AuthnEventIds.INVALID_CREDENTIALS);
+ assertAuthenticationFailureConditions(prc);
+
+ }
+
+
@SuppressWarnings("null")
@Test
public void testUsernamelessFlow_NoAssertionResponse() throws Exception {
@@ -132,7 +241,7 @@ public class TestUsernameslessFlow extends AbstractWebAuthnFlowTest{
final ByteArray challenge = authnContext.getPublicKeyCredentialRequestOptions().getChallenge();
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
- assertionResponse = createAssertionReponseFromCredentialID(
+ assertionResponse = createAssertionReponseFrom(
registration.getCredential().getCredentialId().getBytes(), challenge.getBytes());
final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
@@ -172,7 +281,7 @@ public class TestUsernameslessFlow extends AbstractWebAuthnFlowTest{
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
// Generate a challenge which is not the same as the one generated by the flow
- assertionResponse = createAssertionReponseFromCredentialID(
+ assertionResponse = createAssertionReponseFrom(
registration.getCredential().getCredentialId().getBytes(), generateRandomBytes(32));
final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
@@ -215,7 +324,7 @@ public class TestUsernameslessFlow extends AbstractWebAuthnFlowTest{
final ByteArray challenge = authnContext.getPublicKeyCredentialRequestOptions().getChallenge();
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
- assertionResponse = createAssertionReponseFromCredentialID(
+ assertionResponse = createAssertionReponseFrom(
registration.getCredential().getCredentialId().getBytes(), challenge.getBytes());
final String assertionResponseJson = jsonMapper.writeValueAsString(assertionResponse);
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnTest.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnTest.java
index 51d00af..f826daa 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnTest.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/AbstractWebAuthnTest.java
@@ -395,7 +395,7 @@ public abstract class AbstractWebAuthnTest {
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
return assertion;
}
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentialsFromUserHandleTest.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentialsFromUserHandleTest.java
index d9bde51..c240d97 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentialsFromUserHandleTest.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/LookupRegisteredCredentialsFromUserHandleTest.java
@@ -110,7 +110,7 @@ public class LookupRegisteredCredentialsFromUserHandleTest extends AbstractWebAu
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
webAuthnContext.setPublicKeyCredentialAssertionResponse(assertion);
@@ -165,7 +165,7 @@ public class LookupRegisteredCredentialsFromUserHandleTest extends AbstractWebAu
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
webAuthnContext.setPublicKeyCredentialAssertionResponse(assertion);
@@ -194,7 +194,7 @@ public class LookupRegisteredCredentialsFromUserHandleTest extends AbstractWebAu
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
webAuthnContext.setPublicKeyCredentialAssertionResponse(assertion);
@@ -224,7 +224,7 @@ public class LookupRegisteredCredentialsFromUserHandleTest extends AbstractWebAu
// Now generate an assertion (authentication) and check it is valid
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
webAuthnContext.setPublicKeyCredentialAssertionResponse(assertion);
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertionTest.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertionTest.java
index cd3ed88..a5134ea 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertionTest.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/impl/ValidateWebAuthnAssertionTest.java
@@ -102,7 +102,7 @@ public class ValidateWebAuthnAssertionTest extends AbstractWebAuthnTest {
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
//Set the assertion (authentication) response based on the credential we've already registered
context.setPublicKeyCredentialAssertionResponse(assertion);
@@ -123,7 +123,7 @@ public class ValidateWebAuthnAssertionTest extends AbstractWebAuthnTest {
final PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
assertion = mockAuthenticator.createAuthenticatorAssertionResponse(attestation.getId().getBytes(),
- clientDataGet);
+ clientDataGet, null);
//Set the assertion (authentication) response based on the credential we've already registered
context.setPublicKeyCredentialAssertionResponse(assertion);
diff --git a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/storage/impl/MockAuthenticator.java b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/storage/impl/MockAuthenticator.java
index b9ee8d7..3e29b85 100644
--- a/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/storage/impl/MockAuthenticator.java
+++ b/webauthn-impl/src/test/java/net/shibboleth/idp/plugin/authn/webauthn/storage/impl/MockAuthenticator.java
@@ -218,14 +218,15 @@ public class MockAuthenticator {
*
* @param credentialId the credential identifier to give this credential, should be one that is registered.
* @param clientData the client data passed by the 'client' (browser) during registration.
- *
+ * @param overrideUserHandle if set, override the userHandle in the assertion response. Normally the userHandle
+ * comes from what was stored in the attestation when the key was created.
* @return the public key credential assertion
*
* @throws Exception on error
*/
public com.yubico.webauthn.data.PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs>
- createAuthenticatorAssertionResponse(@Nonnull final byte[] credentialId, final Map<String, String> clientData)
- throws Exception {
+ createAuthenticatorAssertionResponse(@Nonnull final byte[] credentialId, final Map<String, String> clientData,
+ final byte[] overrideUserHandle) throws Exception {
final var credentialb64 = Base64Support.encodeURLSafe(credentialId);
final var publicKeyAttestation = createdCredentialsMaps.get(credentialb64);
@@ -241,13 +242,15 @@ public class MockAuthenticator {
sign(authenticatorData, clientDataCompactSerialization,
publicKeyAttestation.getResponse().getPrivateKey());
+ final var userHandle = overrideUserHandle != null ? overrideUserHandle :
+ publicKeyAttestation.getResponse().getUserHandle();
final var pkCred = new PublicKeyCredential<Assertion, AuthenticatonExtensionsClientOutputs>(rawCredentialIdentifier,
- new Assertion(clientDataCompactSerialization.getBytes(), authenticatorData, signature,
- publicKeyAttestation.getResponse().getUserHandle()),
+ new Assertion(clientDataCompactSerialization.getBytes(), authenticatorData, signature, userHandle),
new AuthenticatonExtensionsClientOutputs());
//convert from the test type to the correct type for the rest of the system
final var assertionAsJson = jsonMapper.writeValueAsString(pkCred);
+ log.debug("Created assertion response '{}'", assertionAsJson);
return com.yubico.webauthn.data.PublicKeyCredential.parseAssertionResponseJson(assertionAsJson);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list