diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingParty.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingParty.java index f8e588eb6..b8f0bafcb 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingParty.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingParty.java @@ -493,7 +493,8 @@ public PublicKeyCredentialCreationOptions startRegistration( .appidExclude(appId) .credProps() .build())) - .timeout(startRegistrationOptions.getTimeout()); + .timeout(startRegistrationOptions.getTimeout()) + .hints(startRegistrationOptions.getHints()); attestationConveyancePreference.ifPresent(builder::attestation); return builder.build(); } @@ -537,7 +538,8 @@ public AssertionRequest startAssertion(StartAssertionOptions startAssertionOptio startAssertionOptions .getExtensions() .merge(startAssertionOptions.getExtensions().toBuilder().appid(appId).build())) - .timeout(startAssertionOptions.getTimeout()); + .timeout(startAssertionOptions.getTimeout()) + .hints(startAssertionOptions.getHints()); startAssertionOptions.getUserVerification().ifPresent(pkcro::userVerification); diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingPartyV2.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingPartyV2.java index 23a71c5bf..9ce2883c3 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingPartyV2.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/RelyingPartyV2.java @@ -452,7 +452,8 @@ public PublicKeyCredentialCreationOptions startRegistration( .appidExclude(appId) .credProps() .build())) - .timeout(startRegistrationOptions.getTimeout()); + .timeout(startRegistrationOptions.getTimeout()) + .hints(startRegistrationOptions.getHints()); attestationConveyancePreference.ifPresent(builder::attestation); return builder.build(); } @@ -509,7 +510,8 @@ public AssertionRequest startAssertion(StartAssertionOptions startAssertionOptio startAssertionOptions .getExtensions() .merge(startAssertionOptions.getExtensions().toBuilder().appid(appId).build())) - .timeout(startAssertionOptions.getTimeout()); + .timeout(startAssertionOptions.getTimeout()) + .hints(startAssertionOptions.getHints()); startAssertionOptions.getUserVerification().ifPresent(pkcro::userVerification); diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/StartAssertionOptions.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/StartAssertionOptions.java index 461f31228..02f2cdba9 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/StartAssertionOptions.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/StartAssertionOptions.java @@ -26,8 +26,13 @@ import com.yubico.webauthn.data.AssertionExtensionInputs; import com.yubico.webauthn.data.ByteArray; +import com.yubico.webauthn.data.PublicKeyCredentialDescriptor; +import com.yubico.webauthn.data.PublicKeyCredentialHint; import com.yubico.webauthn.data.PublicKeyCredentialRequestOptions; import com.yubico.webauthn.data.UserVerificationRequirement; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Optional; import lombok.Builder; import lombok.NonNull; @@ -79,6 +84,55 @@ public class StartAssertionOptions { */ private final Long timeout; + /** + * Zero or more hints, in descending order of preference, to guide the user agent in interacting + * with the user during this authentication operation. + * + *
For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the + * client to emphasize the option of authenticating with an external security key, or the {@link + * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the + * option of authenticating a built-in passkey provider. + * + *
These hints are not requirements, and do not bind the user-agent, but may guide it in + * providing the best experience by using contextual information about the request. + * + *
Hints MAY contradict information contained in {@link + * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence. + * + *
This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument to
+ * navigator.credentials.get()
on the client side.
+ *
+ *
The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see PublicKeyCredentialRequestOptions#getHints()
+ * @see StartAssertionOptionsBuilder#hints(List)
+ * @see StartAssertionOptionsBuilder#hints(String...)
+ * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ private final List Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of authenticating with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of authenticating a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict information contained in {@link
+ * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument
+ * to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see PublicKeyCredentialRequestOptions#getHints()
+ * @see StartAssertionOptions#getHints()
+ * @see StartAssertionOptionsBuilder#hints(List)
+ * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public StartAssertionOptionsBuilder hints(@NonNull String... hints) {
+ this.hints = Arrays.asList(hints);
+ return this;
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this authentication operation.
+ *
+ * Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of authenticating with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of authenticating a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict information contained in {@link
+ * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument
+ * to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see PublicKeyCredentialRequestOptions#getHints()
+ * @see StartAssertionOptions#getHints()
+ * @see StartAssertionOptionsBuilder#hints(List)
+ * @see StartAssertionOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public StartAssertionOptionsBuilder hints(@NonNull PublicKeyCredentialHint... hints) {
+ return this.hints(
+ Arrays.stream(hints).map(PublicKeyCredentialHint::getValue).toArray(String[]::new));
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this authentication operation.
+ *
+ * Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of authenticating with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of authenticating a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict information contained in {@link
+ * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument
+ * to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see PublicKeyCredentialRequestOptions#getHints()
+ * @see StartAssertionOptions#getHints()
+ * @see StartAssertionOptionsBuilder#hints(String...)
+ * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public StartAssertionOptionsBuilder hints(@NonNull List For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this occurs,
+ * the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialCreationOptions} so they can be used in the argument
+ * to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptionsBuilder#hints(List)
+ * @see StartRegistrationOptionsBuilder#hints(String...)
+ * @see StartRegistrationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ private final List Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this
+ * occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialCreationOptions} so they can be used in the argument
+ * to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptions#getHints()
+ * @see StartRegistrationOptionsBuilder#hints(List)
+ * @see StartRegistrationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public StartRegistrationOptionsBuilder hints(@NonNull String... hints) {
+ this.hints = Arrays.asList(hints);
+ return this;
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this registration operation.
+ *
+ * Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this
+ * occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialCreationOptions} so they can be used in the argument
+ * to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptions#getHints()
+ * @see StartRegistrationOptionsBuilder#hints(List)
+ * @see StartRegistrationOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public StartRegistrationOptionsBuilder hints(@NonNull PublicKeyCredentialHint... hints) {
+ return this.hints(
+ Arrays.stream(hints).map(PublicKeyCredentialHint::getValue).toArray(String[]::new));
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this registration operation.
+ *
+ * Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this
+ * occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through to the {@link PublicKeyCredentialCreationOptions} so they can be used in the argument
+ * to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptions#getHints()
+ * @see StartRegistrationOptionsBuilder#hints(String...)
+ * @see StartRegistrationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public StartRegistrationOptionsBuilder hints(@NonNull List For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this occurs,
+ * the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptions#getHints()
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(List)
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ private final List For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this
+ * occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptions#getHints()
+ * @see PublicKeyCredentialCreationOptions#getHints()
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(List)
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public PublicKeyCredentialCreationOptionsBuilder hints(@NonNull String... hints) {
+ this.hints = Arrays.asList(hints);
+ return this;
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this registration operation.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this
+ * occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptions#getHints()
+ * @see PublicKeyCredentialCreationOptions#getHints()
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(List)
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public PublicKeyCredentialCreationOptionsBuilder hints(
+ @NonNull PublicKeyCredentialHint... hints) {
+ return this.hints(
+ Arrays.stream(hints).map(PublicKeyCredentialHint::getValue).toArray(String[]::new));
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this registration operation.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of registering with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of registering a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict preferences in {@link #getAuthenticatorSelection()}. When this
+ * occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartRegistrationOptions#getHints()
+ * @see PublicKeyCredentialCreationOptions#getHints()
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialCreationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public PublicKeyCredentialCreationOptionsBuilder hints(@NonNull List For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of using an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the option
+ * of using a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * @see StartRegistrationOptions#getHints()
+ * @see StartAssertionOptions#getHints()
+ * @see PublicKeyCredentialCreationOptions.hints
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+@Value
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+public class PublicKeyCredentialHint {
+
+ @JsonValue @NonNull private final String value;
+
+ /**
+ * Indicates that the application believes that users will satisfy this request with a physical
+ * security key.
+ *
+ * For example, an enterprise application may set this hint if they have issued security keys
+ * to their employees and will only accept those authenticators for registration and
+ * authentication. In that case, the application should probably also set {@link
+ * RelyingPartyBuilder#attestationTrustSource(AttestationTrustSource) attestationTrustSource} and
+ * set {@link RelyingPartyBuilder#allowUntrustedAttestation(boolean) allowUntrustedAttestation} to
+ * For compatibility with older user agents, when this hint is used in {@link
+ * StartRegistrationOptions}, the For compatibility with older user agents, when this hint is used in {@link
+ * StartRegistrationOptions}, the For compatibility with older user agents, when this hint is used in {@link
+ * StartRegistrationOptions}, the For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of authenticating with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of authenticating a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict information contained in {@link
+ * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartAssertionOptions#getHints()
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(List)
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ private final List Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of authenticating with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of authenticating a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict information contained in {@link
+ * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartAssertionOptions#getHints()
+ * @see PublicKeyCredentialRequestOptions#getHints()
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(List)
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public PublicKeyCredentialRequestOptionsBuilder hints(@NonNull String... hints) {
+ this.hints = Arrays.asList(hints);
+ return this;
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this authentication operation.
+ *
+ * Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of authenticating with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of authenticating a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict information contained in {@link
+ * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartAssertionOptions#getHints()
+ * @see PublicKeyCredentialRequestOptions#getHints()
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(List)
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public PublicKeyCredentialRequestOptionsBuilder hints(
+ @NonNull PublicKeyCredentialHint... hints) {
+ return this.hints(
+ Arrays.stream(hints).map(PublicKeyCredentialHint::getValue).toArray(String[]::new));
+ }
+
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this authentication operation.
+ *
+ * Setting this property multiple times overwrites any value set previously.
+ *
+ * For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
+ * client to emphasize the option of authenticating with an external security key, or the {@link
+ * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
+ * option of authenticating a built-in passkey provider.
+ *
+ * These hints are not requirements, and do not bind the user-agent, but may guide it in
+ * providing the best experience by using contextual information about the request.
+ *
+ * Hints MAY contradict information contained in {@link
+ * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
+ *
+ * This library does not take these hints into account in any way, other than passing them
+ * through so they can be used in the argument to The default is empty.
+ *
+ * @see PublicKeyCredentialHint
+ * @see StartAssertionOptions#getHints()
+ * @see PublicKeyCredentialRequestOptions#getHints()
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(String...)
+ * @see PublicKeyCredentialRequestOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see PublicKeyCredentialRequestOptions.hints
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public PublicKeyCredentialRequestOptionsBuilder hints(@NonNull Listnavigator.credentials.get()
on the client side.
+ *
+ * navigator.credentials.get()
on the client side.
+ *
+ * navigator.credentials.get()
on the client side.
+ *
+ * navigator.credentials.create()
on the client side.
+ *
+ * navigator.credentials.create()
on the client side.
+ *
+ * navigator.credentials.create()
on the client side.
+ *
+ * navigator.credentials.create()
on the client side.
+ *
+ * navigator.credentials.create()
on
+ * the client side.
+ *
+ * navigator.credentials.create()
on
+ * the client side.
+ *
+ * navigator.credentials.create()
on
+ * the client side.
+ *
+ * navigator.credentials.create()
on
+ * the client side.
+ *
+ * false
. See also the
+ * webauthn-server-attestation
module.
+ *
+ *
+ * {@link StartRegistrationOptionsBuilder#authenticatorSelection(AuthenticatorSelectionCriteria) authenticatorSelection}.{@link AuthenticatorSelectionCriteria.AuthenticatorSelectionCriteriaBuilder#authenticatorAttachment(AuthenticatorAttachment) authenticatorAttachment}
+ *
parameter SHOULD be set to {@link AuthenticatorAttachment#CROSS_PLATFORM}.
+ *
+ * @see StartRegistrationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see
+ * security-key
in §5.8.7. User-agent Hints Enumeration (enum
+ * PublicKeyCredentialHints)
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public static final PublicKeyCredentialHint SECURITY_KEY =
+ new PublicKeyCredentialHint("security-key");
+
+ /**
+ * Indicates that the application believes that users will satisfy this request with an
+ * authenticator built into the client device.
+ *
+ *
+ * {@link StartRegistrationOptionsBuilder#authenticatorSelection(AuthenticatorSelectionCriteria) authenticatorSelection}.{@link AuthenticatorSelectionCriteria.AuthenticatorSelectionCriteriaBuilder#authenticatorAttachment(AuthenticatorAttachment) authenticatorAttachment}
+ *
parameter SHOULD be set to {@link AuthenticatorAttachment#PLATFORM}.
+ *
+ * @see StartRegistrationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see
+ * client-device
in §5.8.7. User-agent Hints Enumeration (enum
+ * PublicKeyCredentialHints)
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public static final PublicKeyCredentialHint CLIENT_DEVICE =
+ new PublicKeyCredentialHint("client-device");
+
+ /**
+ * Indicates that the application believes that users will satisfy this request with
+ * general-purpose authenticators such as smartphones. For example, a consumer application may
+ * believe that only a small fraction of their customers possesses dedicated security keys. This
+ * option also implies that the local platform authenticator should not be promoted in the UI.
+ *
+ *
+ * {@link StartRegistrationOptionsBuilder#authenticatorSelection(AuthenticatorSelectionCriteria) authenticatorSelection}.{@link AuthenticatorSelectionCriteria.AuthenticatorSelectionCriteriaBuilder#authenticatorAttachment(AuthenticatorAttachment) authenticatorAttachment}
+ *
parameter SHOULD be set to {@link AuthenticatorAttachment#CROSS_PLATFORM}.
+ *
+ * @see StartRegistrationOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
+ * @see
+ * hybrid
in §5.8.7. User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ *
+ * @see §5.8.7.
+ * User-agent Hints Enumeration (enum PublicKeyCredentialHints)
+ */
+ public static final PublicKeyCredentialHint HYBRID = new PublicKeyCredentialHint("hybrid");
+
+ /**
+ * @return An array containing all predefined values of {@link PublicKeyCredentialHint} known by
+ * this implementation.
+ */
+ public static PublicKeyCredentialHint[] values() {
+ return new PublicKeyCredentialHint[] {SECURITY_KEY, CLIENT_DEVICE, HYBRID};
+ }
+
+ /**
+ * @return If value
is the same as that of any of {@link #SECURITY_KEY}, {@link
+ * #CLIENT_DEVICE} or {@link #HYBRID}, returns that constant instance. Otherwise returns a new
+ * instance containing value
.
+ * @see #valueOf(String)
+ */
+ @JsonCreator
+ public static PublicKeyCredentialHint of(@NonNull String value) {
+ return Stream.of(values())
+ .filter(v -> v.getValue().equals(value))
+ .findAny()
+ .orElseGet(() -> new PublicKeyCredentialHint(value));
+ }
+
+ /**
+ * @return If name
equals "SECURITY_KEY"
, "CLIENT_DEVICE"
+ * or "HYBRID"
, returns the constant by that name.
+ * @throws IllegalArgumentException if name
is anything else.
+ * @see #of(String)
+ */
+ public static PublicKeyCredentialHint valueOf(String name) {
+ switch (name) {
+ case "SECURITY_KEY":
+ return SECURITY_KEY;
+ case "CLIENT_DEVICE":
+ return CLIENT_DEVICE;
+ case "HYBRID":
+ return HYBRID;
+ default:
+ throw new IllegalArgumentException(
+ "No constant com.yubico.webauthn.data.PublicKeyCredentialHint." + name);
+ }
+ }
+}
diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredentialRequestOptions.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredentialRequestOptions.java
index 4834d81a4..da37870cc 100644
--- a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredentialRequestOptions.java
+++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/PublicKeyCredentialRequestOptions.java
@@ -31,6 +31,9 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yubico.internal.util.CollectionUtil;
import com.yubico.internal.util.JacksonCodecs;
+import com.yubico.webauthn.StartAssertionOptions;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
import lombok.Builder;
@@ -66,6 +69,40 @@ public class PublicKeyCredentialRequestOptions {
*/
private final Long timeout;
+ /**
+ * Zero or more hints, in descending order of preference, to guide the user agent in interacting
+ * with the user during this authentication operation.
+ *
+ * navigator.credentials.get()
on the
+ * client side.
+ *
+ * navigator.credentials.get()
on
+ * the client side.
+ *
+ * navigator.credentials.get()
on
+ * the client side.
+ *
+ * navigator.credentials.get()
on
+ * the client side.
+ *
+ *