AuthenticatorAssertionResponse.java
/*
* Copyright 2004-present the original author or authors.
*
* 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
*
* https://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 org.springframework.security.web.webauthn.api;
import java.io.Serial;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
* The <a href=
* "https://www.w3.org/TR/webauthn-3/#authenticatorassertionresponse">AuthenticatorAssertionResponse</a>
* interface represents an
* <a href="https://www.w3.org/TR/webauthn-3/#authenticator">authenticator</a>'s response
* to a client's request for generation of a new
* <a href="https://www.w3.org/TR/webauthn-3/#authentication-assertion">authentication
* assertion</a> given the
* <a href="https://www.w3.org/TR/webauthn-3/#webauthn-relying-party">WebAuthn Relying
* Party</a>'s challenge and OPTIONAL list of credentials it is aware of. This response
* contains a cryptographic signature proving possession of the
* <a href="https://www.w3.org/TR/webauthn-3/#credential-private-key">credential private
* key</a>, and optionally evidence of
* <a href="https://www.w3.org/TR/webauthn-3/#user-consent">user consent</a> to a specific
* transaction.
*
* @author Rob Winch
* @since 6.4
* @see PublicKeyCredential#getResponse()
*/
public final class AuthenticatorAssertionResponse extends AuthenticatorResponse {
@Serial
private static final long serialVersionUID = 324976481675434298L;
private final Bytes authenticatorData;
private final Bytes signature;
private final @Nullable Bytes userHandle;
private final @Nullable Bytes attestationObject;
private AuthenticatorAssertionResponse(Bytes clientDataJSON, Bytes authenticatorData, Bytes signature,
@Nullable Bytes userHandle, @Nullable Bytes attestationObject) {
super(clientDataJSON);
this.authenticatorData = authenticatorData;
this.signature = signature;
this.userHandle = userHandle;
this.attestationObject = attestationObject;
}
/**
* The <a href=
* "https://www.w3.org/TR/webauthn-3/#dom-authenticatorassertionresponse-authenticatordata">authenticatorData</a>
* contains the
* <a href="https://www.w3.org/TR/webauthn-3/#authenticator-data">authenticator
* data</a> returned by the authenticator. See
* <a href="https://www.w3.org/TR/webauthn-3/#sctn-authenticator-data">6.1
* Authenticator Data.</a>.
* @return the {@code authenticatorData}
*/
public Bytes getAuthenticatorData() {
return this.authenticatorData;
}
/**
* The <a href=
* "https://www.w3.org/TR/webauthn-3/#dom-authenticatorassertionresponse-signature">signature</a>
* contains the raw signature returned from the authenticator. See
* <a href="https://www.w3.org/TR/webauthn-3/#sctn-op-get-assertion">6.3.3 The
* authenticatorGetAssertion Operation</a>.
* @return the {@code signature}
*/
public Bytes getSignature() {
return this.signature;
}
/**
* The <a href=
* "https://www.w3.org/TR/webauthn-3/#dom-authenticatorassertionresponse-userhandle">userHandle</a>
* is the <a href="https://www.w3.org/TR/webauthn-3/#user-handle">user handle</a>
* which is returned from the authenticator, or null if the authenticator did not
* return a user handle. See
* <a href="https://www.w3.org/TR/webauthn-3/#sctn-op-get-assertion">6.3.3 The
* authenticatorGetAssertion Operation</a>. The authenticator MUST always return a
* user handle if the <a href=
* "https://www.w3.org/TR/webauthn-3/#dom-publickeycredentialrequestoptions-allowcredentials">allowCredentials</a>
* option used in the
* <a href="https://www.w3.org/TR/webauthn-3/#authentication-ceremony">authentication
* ceremony</a> is empty, and MAY return one otherwise.
* @return the <a href="https://www.w3.org/TR/webauthn-3/#user-handle">user handle</a>
*/
public @Nullable Bytes getUserHandle() {
return this.userHandle;
}
/**
* The <a href=
* "https://www.w3.org/TR/webauthn-3/#dom-authenticatorattestationresponse-attestationobject">attestationObject</a>
* is an OPTIONAL attribute contains an
* <a href="https://www.w3.org/TR/webauthn-3/#attestation-object">attestation
* object</a>, if the authenticator supports attestation in assertions.
* @return the {@code attestationObject}
*/
public @Nullable Bytes getAttestationObject() {
return this.attestationObject;
}
/**
* Creates a new {@link AuthenticatorAssertionResponseBuilder}
* @return the {@link AuthenticatorAssertionResponseBuilder}
*/
public static AuthenticatorAssertionResponseBuilder builder() {
return new AuthenticatorAssertionResponseBuilder();
}
/**
* Builds a {@link AuthenticatorAssertionResponse}.
*
* @author Rob Winch
* @since 6.4
*/
public static final class AuthenticatorAssertionResponseBuilder {
private @Nullable Bytes authenticatorData;
private @Nullable Bytes signature;
private @Nullable Bytes userHandle;
private @Nullable Bytes attestationObject;
private @Nullable Bytes clientDataJSON;
private AuthenticatorAssertionResponseBuilder() {
}
/**
* Set the {@link #getAuthenticatorData()} property
* @param authenticatorData the authenticator data.
* @return the {@link AuthenticatorAssertionResponseBuilder}
*/
public AuthenticatorAssertionResponseBuilder authenticatorData(Bytes authenticatorData) {
this.authenticatorData = authenticatorData;
return this;
}
/**
* Set the {@link #getSignature()} property
* @param signature the signature
* @return the {@link AuthenticatorAssertionResponseBuilder}
*/
public AuthenticatorAssertionResponseBuilder signature(Bytes signature) {
this.signature = signature;
return this;
}
/**
* Set the {@link #getUserHandle()} property
* @param userHandle the user handle
* @return the {@link AuthenticatorAssertionResponseBuilder}
*/
public AuthenticatorAssertionResponseBuilder userHandle(Bytes userHandle) {
this.userHandle = userHandle;
return this;
}
/**
* Set the {@link #attestationObject} property
* @param attestationObject the attestation object
* @return the {@link AuthenticatorAssertionResponseBuilder}
*/
public AuthenticatorAssertionResponseBuilder attestationObject(Bytes attestationObject) {
this.attestationObject = attestationObject;
return this;
}
/**
* Set the {@link #getClientDataJSON()} property
* @param clientDataJSON the client data JSON
* @return the {@link AuthenticatorAssertionResponseBuilder}
*/
public AuthenticatorAssertionResponseBuilder clientDataJSON(Bytes clientDataJSON) {
this.clientDataJSON = clientDataJSON;
return this;
}
/**
* Builds the {@link AuthenticatorAssertionResponse}
* @return the {@link AuthenticatorAssertionResponse}
*/
public AuthenticatorAssertionResponse build() {
Assert.notNull(this.clientDataJSON, "clientDataJSON cannot be null");
Assert.notNull(this.authenticatorData, "authenticatorData cannot be null");
Assert.notNull(this.signature, "signature cannot be null");
return new AuthenticatorAssertionResponse(this.clientDataJSON, this.authenticatorData, this.signature,
this.userHandle, this.attestationObject);
}
}
}