ImmutablePublicKeyCredentialUserEntity.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;
/**
* <a href=
* "https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialuserentity">PublicKeyCredentialUserEntity</a>
* is used to supply additional
* <a href="https://www.w3.org/TR/webauthn-3/#user-account">user account</a> attributes
* when creating a new credential.
*
* @author Rob Winch
* @since 6.4
*/
public final class ImmutablePublicKeyCredentialUserEntity implements PublicKeyCredentialUserEntity {
@Serial
private static final long serialVersionUID = -3438693960347279759L;
/**
* When inherited by PublicKeyCredentialUserEntity, it is a human-palatable identifier
* for a user account. It is intended only for display, i.e., aiding the user in
* determining the difference between user accounts with similar displayNames. For
* example, "alexm", "alex.mueller@example.com" or "+14255551234".
*
* The Relying Party MAY let the user choose this value. The Relying Party SHOULD
* perform enforcement, as prescribed in Section 3.4.3 of [RFC8265] for the
* UsernameCasePreserved Profile of the PRECIS IdentifierClass [RFC8264], when setting
* name's value, or displaying the value to the user.
*
* This string MAY contain language and direction metadata. Relying Parties SHOULD
* consider providing this information. See 6.4.2 Language and Direction Encoding
* about how this metadata is encoded.
*
* Clients SHOULD perform enforcement, as prescribed in Section 3.4.3 of [RFC8265] for
* the UsernameCasePreserved Profile of the PRECIS IdentifierClass [RFC8264], on
* name's value prior to displaying the value to the user or including the value as a
* parameter of the authenticatorMakeCredential operation.
*/
private final String name;
/**
* The user handle of the user account entity. A user handle is an opaque byte
* sequence with a maximum size of 64 bytes, and is not meant to be displayed to the
* user.
*
* To ensure secure operation, authentication and authorization decisions MUST be made
* on the basis of this id member, not the displayName nor name members. See Section
* 6.1 of [RFC8266].
*
* The user handle MUST NOT contain personally identifying information about the user,
* such as a username or e-mail address; see 14.6.1 User Handle Contents for details.
* The user handle MUST NOT be empty, though it MAY be null.
*
* Note: the user handle ought not be a constant value across different accounts, even
* for non-discoverable credentials, because some authenticators always create
* discoverable credentials. Thus a constant user handle would prevent a user from
* using such an authenticator with more than one account at the Relying Party.
*/
private final Bytes id;
/**
* A human-palatable name for the user account, intended only for display. The Relying
* Party SHOULD let the user choose this, and SHOULD NOT restrict the choice more than
* necessary.
*
* Relying Parties SHOULD perform enforcement, as prescribed in Section 2.3 of
* [RFC8266] for the Nickname Profile of the PRECIS FreeformClass [RFC8264], when
* setting displayName's value, or displaying the value to the user.
*
* This string MAY contain language and direction metadata. Relying Parties SHOULD
* consider providing this information. See 6.4.2 Language and Direction Encoding
* about how this metadata is encoded.
*
* Clients SHOULD perform enforcement, as prescribed in Section 2.3 of [RFC8266] for
* the Nickname Profile of the PRECIS FreeformClass [RFC8264], on displayName's value
* prior to displaying the value to the user or including the value as a parameter of
* the authenticatorMakeCredential operation.
*
* When clients, client platforms, or authenticators display a displayName's value,
* they should always use UI elements to provide a clear boundary around the displayed
* value, and not allow overflow into other elements [css-overflow-3].
*
* Authenticators MUST accept and store a 64-byte minimum length for a displayName
* member's value. Authenticators MAY truncate a displayName member's value so that it
* fits within 64 bytes. See 6.4.1 String Truncation about truncation and other
* considerations.
*/
private final @Nullable String displayName;
private ImmutablePublicKeyCredentialUserEntity(String name, Bytes id, @Nullable String displayName) {
this.name = name;
this.id = id;
this.displayName = displayName;
}
@Override
public String getName() {
return this.name;
}
@Override
public Bytes getId() {
return this.id;
}
@Override
public @Nullable String getDisplayName() {
return this.displayName;
}
/**
* Create a new {@link PublicKeyCredentialUserEntityBuilder}
* @return a new {@link PublicKeyCredentialUserEntityBuilder}
*/
public static PublicKeyCredentialUserEntityBuilder builder() {
return new PublicKeyCredentialUserEntityBuilder();
}
/**
* Used to build {@link PublicKeyCredentialUserEntity}.
*
* @author Rob Winch
* @since 6.4
*/
public static final class PublicKeyCredentialUserEntityBuilder {
@SuppressWarnings("NullAway.Init")
private String name;
@SuppressWarnings("NullAway.Init")
private Bytes id;
private @Nullable String displayName;
private PublicKeyCredentialUserEntityBuilder() {
}
/**
* Sets the {@link #getName()} property.
* @param name the name
* @return the {@link PublicKeyCredentialUserEntityBuilder}
*/
public PublicKeyCredentialUserEntityBuilder name(String name) {
this.name = name;
return this;
}
/**
* Sets the {@link #getId()} property.
* @param id the id
* @return the {@link PublicKeyCredentialUserEntityBuilder}
*/
public PublicKeyCredentialUserEntityBuilder id(Bytes id) {
this.id = id;
return this;
}
/**
* Sets the {@link #getDisplayName()} property.
* @param displayName the display name
* @return the {@link PublicKeyCredentialUserEntityBuilder}
*/
public PublicKeyCredentialUserEntityBuilder displayName(String displayName) {
this.displayName = displayName;
return this;
}
/**
* Builds a new {@link PublicKeyCredentialUserEntity}
* @return a new {@link PublicKeyCredentialUserEntity}
*/
public PublicKeyCredentialUserEntity build() {
return new ImmutablePublicKeyCredentialUserEntity(this.name, this.id, this.displayName);
}
}
}