in app/logic/Passkey.scala [106:192]
def authenticationOptions(
user: UserIdentity,
challenge: Challenge = new DefaultChallenge()
): Try[PublicKeyCredentialRequestOptions] =
Try(
new PublicKeyCredentialRequestOptions(
challenge,
null,
null,
null,
null,
null
)
).recoverWith(exception =>
Failure(
JanusException(
userMessage = "Failed to create authentication options",
engineerMessage =
s"Failed to create authentication options for user ${user.username}: ${exception.getMessage}",
httpCode = BAD_REQUEST,
causedBy = Some(exception)
)
)
)
/** Verifies the registration response from the browser. This is called after
* the user has completed the passkey creation process on the browser.
*
* See
* [[https://webauthn4j.github.io/webauthn4j/en/#registering-the-webauthn-public-key-credential-on-the-server]].
*
* @param appHost
* The host of the application the passkey will authenticate (the relying
* party).
* @param challenge
* Must correspond with the challenge passed in [[registrationOptions]]).
* @param jsonResponse
* The JSON response from the browser containing the registration data.
* @return
* A CredentialRecord object containing the verified credential data or an
* [[IllegalArgumentException]] if verification fails.
*/
def verifiedRegistration(
appHost: String,
challenge: Challenge,
jsonResponse: String
): Try[CredentialRecord] =
Try {
val regData = webAuthnManager.parseRegistrationResponseJSON(jsonResponse)
val regParams = new RegistrationParameters(
new ServerProperty(
Origin.create(appHost),
URI.create(appHost).getHost,
challenge
),
publicKeyCredentialParameters.asJava,
userVerificationRequired
)
val verified = webAuthnManager.verify(regData, regParams)
new CredentialRecordImpl(
verified.getAttestationObject,
verified.getCollectedClientData,
verified.getClientExtensions,
verified.getTransports
)
}.recoverWith {
case exception: VerificationException =>
Failure(
JanusException(
userMessage = "Registration verification failed",
engineerMessage =
s"Registration verification failed: ${exception.getMessage}",
httpCode = BAD_REQUEST,
causedBy = Some(exception)
)
)
case exception =>
Failure(
JanusException(
userMessage = "Bad arguments for registration verification request",
engineerMessage =
s"Bad arguments for registration verification request: ${exception.getMessage}",
httpCode = BAD_REQUEST,
causedBy = Some(exception)
)
)
}