Replace Security Key with Passkey in WebAuthn UIs and their documents

closes #27147

Signed-off-by: Takashi Norimatsu <takashi.norimatsu.ws@hitachi.com>
This commit is contained in:
Takashi Norimatsu 2024-02-20 11:19:30 +09:00 committed by Marek Posolda
parent 8dd0eb451d
commit 3db04d8d8d
19 changed files with 69 additions and 70 deletions

View file

@ -31,10 +31,10 @@ Thanks to https://github.com/thomasdarimont[Thomas Darimont] for the contributio
Keycloak has preview support for https://fidoalliance.org/passkeys/[Passkeys].
Passkey registration and authentication are realized by the features of WebAuthn.
Therefore, users of Keycloak can do passkey registration and authentication by existing WebAuthn registration and authentication.
Therefore, users of Keycloak can do Passkey registration and authentication by existing WebAuthn registration and authentication.
Both synced passkeys and device-bound passkeys can be used for both Same-Device and Cross-Device Authentication.
However, passkeys operations success depends on the user's environment. Make sure which operations can succeed in https://passkeys.dev/device-support/[the environment].
Both synced Passkeys and device-bound Passkeys can be used for both Same-Device and Cross-Device Authentication.
However, Passkeys operations success depends on the user's environment. Make sure which operations can succeed in https://passkeys.dev/device-support/[the environment].
Thanks to https://github.com/tnorimat[Takashi Norimatsu] for the contribution and thanks to https://github.com/thomasdarimont[Thomas Darimont] for the help with the
ideas and testing of this feature.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View file

@ -53,16 +53,16 @@ image:images/account-console-signing-in.png[Signing in]
.Procedure
. Click *Account Security* in the menu.
. Click *Signing in*.
. Click *Set up Security Key*.
. Click *Signing In*.
. Click *Set up a Passkey*.
+
.Signing In
image:images/account-console-signing-in-webauthn-2factor.png[Signing In With Security Key]
image:images/account-console-signing-in-webauthn-2factor.png[Signing in with a Passkey]
. Prepare your WebAuthn Security Key. How you prepare this key depends on the type of WebAuthn security key you use. For example, for a USB based Yubikey, you may need to put your key into the USB port on your laptop.
. Click *Register* to register your security key.
. Prepare your Passkey. How you prepare this key depends on the type of Passkey you use. For example, for a USB based Yubikey, you may need to put your key into the USB port on your laptop.
. Click *Register* to register your Passkey.
. Log out and log in again.
. Assuming authentication flow was correctly set, a message appears asking you to authenticate with your Security Key as second factor.
. Assuming authentication flow was correctly set, a message appears asking you to authenticate with your Passkey as second factor.
==== Passwordless authentication with WebAuthn
@ -74,16 +74,15 @@ image:images/account-console-signing-in-webauthn-2factor.png[Signing In With Sec
. Click *Account Security* in the menu.
. Click *Signing In*.
. Click *Set up Security Key* in the *Passwordless* section.
. Click *Set up a Passkey* in the *Passwordless* section.
+
.Signing In
image:images/account-console-signing-in-webauthn-passwordless.png[Signing In With Security Key]
image:images/account-console-signing-in-webauthn-passwordless.png[Signing in with a Passkey]
. Prepare your WebAuthn Security Key. How you prepare this key depends on the type of WebAuthn security key you use. For example, for a USB based Yubikey, you may need to put your key into the USB port on your laptop.
. Click *Register* to register your security key.
. Prepare your Passkey. How you prepare this key depends on the type of Passkey you use. For example, for a USB based Yubikey, you may need to put your key into the USB port on your laptop.
. Click *Register* to register your Passkey.
. Log out and log in again.
. Assuming authentication flow was correctly set, a message appears asking you to authenticate with your Security Key as second factor. You no longer need to provide your password to log in.
. Assuming authentication flow was correctly set, a message appears asking you to authenticate with your Passkey as second factor. You no longer need to provide your password to log in.
=== Viewing device activity

View file

@ -219,7 +219,7 @@ After entering the username, the flow works as follows:
If users have WebAuthn passwordless credentials recorded, they can use these credentials to log in directly. This is the password-less login. The user can also select *Password with OTP* because the `WebAuthn Passwordless` execution and the `Password with OTP` flow are set to *Alternative*. If they are set to *Required*, the user has to enter WebAuthn, password, and OTP.
If the user selects the *Try another way* link with `WebAuthn passwordless` authentication, the user can choose between `Password` and `Security Key` (WebAuthn passwordless). When selecting the password, the user will need to continue and log in with the assigned OTP. If the user has no WebAuthn credentials, the user must enter the password and then the OTP. If the user has no OTP credential, they will be asked to record one.
If the user selects the *Try another way* link with `WebAuthn passwordless` authentication, the user can choose between `Password` and `Passkey` (WebAuthn passwordless). When selecting the password, the user will need to continue and log in with the assigned OTP. If the user has no WebAuthn credentials, the user must enter the password and then the OTP. If the user has no OTP credential, they will be asked to record one.
[NOTE]
====

View file

@ -4,10 +4,10 @@
{project_name} provides preview support for https://fidoalliance.org/passkeys/[Passkeys]. {project_name} works as a Passkeys Relying Party (RP).
Passkey registration and authentication are realized by the features of xref:webauthn_{context}[WebAuthn].
Therefore, users of {project_name} can do passkey registration and authentication by existing xref:webauthn_{context}[WebAuthn registration and authentication].
Therefore, users of {project_name} can do Passkey registration and authentication by existing xref:webauthn_{context}[WebAuthn registration and authentication].
[NOTE]
====
Both synced passkeys and device-bound passkeys can be used for both Same-Device and Cross-Device Authentication (CDA).
However, passkeys operations success depends on the user's environment. Make sure which operations can succeed in https://passkeys.dev/device-support/[the environment].
Both synced Passkeys and device-bound Passkeys can be used for both Same-Device and Cross-Device Authentication (CDA).
However, Passkeys operations success depends on the user's environment. Make sure which operations can succeed in https://passkeys.dev/device-support/[the environment].
====

View file

@ -162,7 +162,7 @@ The appropriate method to register a WebAuthn authenticator depends on whether t
===== New user
If the *WebAuthn Register* required action is *Default Action* in a realm, new users must set up the WebAuthn security key after their first login.
If the *WebAuthn Register* required action is *Default Action* in a realm, new users must set up the Passkey after their first login.
.Procedure
@ -191,7 +191,7 @@ After successful registration, the user's browser asks the user to enter the tex
{project_name} uses WebAuthn for two-factor authentication, but you can use WebAuthn as the first-factor authentication. In this case, users with `passwordless` WebAuthn credentials can authenticate to {project_name} without a password. {project_name} can use WebAuthn as both the passwordless and two-factor authentication mechanism in the context of a realm and a single authentication flow.
An administrator typically requires that Security Keys registered by users for the WebAuthn passwordless authentication meet different requirements. For example, the security keys may require users to authenticate to the security key using a PIN, or the security key attests with a stronger certificate authority.
An administrator typically requires that Passkeys registered by users for the WebAuthn passwordless authentication meet different requirements. For example, the Passkeys may require users to authenticate to the Passkey using a PIN, or the Passkey attests with a stronger certificate authority.
Because of this, {project_name} permits administrators to configure a separate `WebAuthn Passwordless Policy`. There is a required `Webauthn Register Passwordless` action of type and separate authenticator of type `WebAuthn Passwordless Authenticator`.
@ -201,7 +201,7 @@ Set up WebAuthn passwordless support as follows:
. (if not already present) Register a new required action for WebAuthn passwordless support. Use the steps described in <<_webauthn-register, Enable WebAuthn Authenticator Registration>>. Register the `Webauthn Register Passwordless` action.
. Configure the policy. You can use the steps and configuration options described in <<_webauthn-policy, Managing Policy>>. Perform the configuration in the Admin Console in the tab *WebAuthn Passwordless Policy*. Typically the requirements for the security key will be stronger than for the two-factor policy. For example, you can set the *User Verification Requirement* to *Required* when you configure the passwordless policy.
. Configure the policy. You can use the steps and configuration options described in <<_webauthn-policy, Managing Policy>>. Perform the configuration in the Admin Console in the tab *WebAuthn Passwordless Policy*. Typically the requirements for the Passkey will be stronger than for the two-factor policy. For example, you can set the *User Verification Requirement* to *Required* when you configure the passwordless policy.
. Configure the authentication flow. Use the *WebAuthn Browser* flow described in <<_webauthn-authenticator-setup, Adding WebAuthn Authentication to a Browser Flow>>. Configure the flow as follows:
+
@ -225,7 +225,7 @@ You can now add *WebAuthn Register Passwordless* as the required action to a use
{project_name} uses WebAuthn for two-factor authentication, but you can use WebAuthn as the first-factor authentication. In this case, users with `passwordless` WebAuthn credentials can authenticate to {project_name} without submitting a login or a password. {project_name} can use WebAuthn as both the loginless/passwordless and two-factor authentication mechanism in the context of a realm.
An administrator typically requires that Security Keys registered by users for the WebAuthn loginless authentication meet different requirements. Loginless authentication requires users to authenticate to the security key (for example by using a PIN code or a fingerprint) and that the cryptographic keys associated with the loginless credential are stored physically on the security key. Not all security keys meet that kind of requirements. Check with your security key vendor if your device supports 'user verification' and 'discoverable credential'. See <<_webauthn-supported-keys, Supported Security Keys>>.
An administrator typically requires that Passkeys registered by users for the WebAuthn loginless authentication meet different requirements. Loginless authentication requires users to authenticate to the Passkey (for example by using a PIN code or a fingerprint) and that the cryptographic keys associated with the loginless credential are stored physically on the Passkey. Not all Passkeys meet that kind of requirement. Check with your Passkey vendor if your device supports 'user verification' and 'discoverable credential'. See <<_webauthn-supported-keys, Supported Passkeys>>.
{project_name} permits administrators to configure the `WebAuthn Passwordless Policy` in a way that allows loginless authentication. Note that loginless authentication can only be configured with `WebAuthn Passwordless Policy` and with `WebAuthn Passwordless` credentials. WebAuthn loginless authentication and WebAuthn passwordless authentication can be configured on the same realm but will share the same policy `WebAuthn Passwordless Policy`.
@ -236,7 +236,7 @@ Set up WebAuthn Loginless support as follows:
. (if not already present) Register a new required action for WebAuthn passwordless support. Use the steps described in <<_webauthn-register, Enable WebAuthn Authenticator Registration>>. Register the `Webauthn Register Passwordless` action.
. Configure the `WebAuthn Passwordless Policy`. Perform the configuration in the Admin Console, `Authentication` section, in the tab `Policies` -> `WebAuthn Passwordless Policy`. You have to set *User Verification Requirement* to *required* and *Require Discoverable Credential* to *Yes* when you configure the policy for loginless scenario. Note that since there isn't a dedicated Loginless policy it won't be possible to mix authentication scenarios with user verification=no/discoverable credential=no and loginless scenarios (user verification=yes/discoverable credential=yes). Storage capacity is usually very limited on security keys meaning that you won't be able to store many discoverable credentials on your security key.
. Configure the `WebAuthn Passwordless Policy`. Perform the configuration in the Admin Console, `Authentication` section, in the tab `Policies` -> `WebAuthn Passwordless Policy`. You have to set *User Verification Requirement* to *required* and *Require Discoverable Credential* to *Yes* when you configure the policy for loginless scenario. Note that since there isn't a dedicated Loginless policy it won't be possible to mix authentication scenarios with user verification=no/discoverable credential=no and loginless scenarios (user verification=yes/discoverable credential=yes). Storage capacity is usually very limited on Passkeys meaning that you won't be able to store many discoverable credentials on your Passkey.
. Configure the authentication flow. Create a new authentication flow, add the "WebAuthn Passwordless" execution and set the Requirement setting of the execution to *Required*
@ -245,26 +245,26 @@ The final configuration of the flow looks similar to this:
.LoginLess flow
image:images/webauthn-loginless-flow.png[LoginLess flow]
You can now add the required action `WebAuthn Register Passwordless` to a user, already known to {project_name}, to test this. The user with the required action configured will have to authenticate (with a username/password for example) and will then be prompted to register a security key to be used for loginless authentication.
You can now add the required action `WebAuthn Register Passwordless` to a user, already known to {project_name}, to test this. The user with the required action configured will have to authenticate (with a username/password for example) and will then be prompted to register a Passkey to be used for loginless authentication.
===== Vendor specific remarks
====== Compatibility check list
Loginless authentication with {project_name} requires the security key to meet the following features
Loginless authentication with {project_name} requires the Passkey to meet the following features
** FIDO2 compliance: not to be confused with FIDO/U2F
** User verification: the ability for the security key to authenticate the user (prevents someone finding your security key to be able to authenticate loginless and passwordless)
** Discoverable Credential: the ability for the security key to store the login and the cryptographic keys associated with the client application
** User verification: the ability for the Passkey to authenticate the user (prevents someone finding your Passkey to be able to authenticate loginless and passwordless)
** Discoverable Credential: the ability for the Passkey to store the login and the cryptographic keys associated with the client application
====== Windows Hello
To use Windows Hello based credentials to authenticate against {project_name}, configure the *Signature Algorithms* setting of the `WebAuthn Passwordless Policy` to include the *RS256* value. Note that some browsers don't allow access to platform security key (like Windows Hello) inside private windows.
To use Windows Hello based credentials to authenticate against {project_name}, configure the *Signature Algorithms* setting of the `WebAuthn Passwordless Policy` to include the *RS256* value. Note that some browsers don't allow access to platform Passkey (like Windows Hello) inside private windows.
[[_webauthn-supported-keys]]
====== Supported security keys
====== Supported Passkeys
The following security keys have been successfully tested for loginless authentication with {project_name}:
The following Passkeys have been successfully tested for loginless authentication with {project_name}:
* Windows Hello (Windows 10 21H1/21H2)
* Yubico Yubikey 5 NFC

View file

@ -180,9 +180,9 @@ unLinkSuccess=Successfully unlinked account
applications=Applications
sharedWithMe=Shared with Me
username=Username
webauthn-display-name=Security Key
webauthn-help-text=Use your security key to sign in.
webauthn-passwordless-display-name=Security Key
webauthn-passwordless-help-text=Use your security key for passwordless sign in.
webauthn-display-name=Passkey
webauthn-help-text=Use your Passkey to sign in.
webauthn-passwordless-display-name=Passkey
webauthn-passwordless-help-text=Use your Passkey for passwordless sign in.
passwordless=Passwordless
error-invalid-multivalued-size=Attribute {{0}} must have at least {{1}} and at most {{2}} value(s).

View file

@ -90,7 +90,7 @@ public class CredentialTypeMetadata implements Comparable<CredentialTypeMetadata
/**
* @return the label, which will be shown to the end user on various screens, like login screen with available authentication mechanisms.
* This label will reference this particular authenticator type.
* It should be clear to end users. For example, implementations can return "Authenticator Application" for OTP or "Security Key" for WebAuthn.
* It should be clear to end users. For example, implementations can return "Authenticator Application" for OTP or "Passkey" for WebAuthn.
*
* Alternatively, this method can return a message key, so that it is possible to localize it for various languages.
*/

View file

@ -29,11 +29,11 @@ public class SelectAuthenticatorPage extends LanguageComboboxAwarePage {
public static final String AUTHENTICATOR_APPLICATION = "Authenticator Application";
// Corresponds to the WebAuthn authenticators
public static final String SECURITY_KEY = "Security Key";
public static final String SECURITY_KEY = "Passkey";
public static final String RECOVERY_AUTHN_CODES = "Recovery Authentication Code";
/**
* Return list of names like for example [ "Password", "Authenticator Application", "Security Key" ]
* Return list of names like for example [ "Password", "Authenticator Application", "Passkey" ]
*/
public List<String> getAvailableLoginMethods() {
List<WebElement> rows = getLoginMethodsRows();

View file

@ -67,7 +67,7 @@ public class WebAuthnRegisterPage extends LogoutSessionsPage {
public void registerWebAuthnCredential(String authenticatorLabel) {
if (!isRegisterAlertPresent(ALERT_DEFAULT_TIMEOUT)) {
throw new TimeoutException("Cannot register Security Key due to missing prompt for registration");
throw new TimeoutException("Cannot register Passkey due to missing prompt for registration");
}
Alert promptDialog = driver.switchTo().alert();
@ -114,7 +114,7 @@ public class WebAuthnRegisterPage extends LogoutSessionsPage {
@Override
public boolean isCurrent() {
final String formTitle = getFormTitle();
return formTitle != null && formTitle.equals("Security Key Registration") &&
return formTitle != null && formTitle.equals("Passkey Registration") &&
driver.getPageSource().contains("navigator.credentials.create");
}

View file

@ -251,7 +251,7 @@ public abstract class AbstractWebAuthnVirtualTest extends AbstractTestRealmKeycl
}
/**
* Helper method for registering Security Key
* Helper method for registering Passkey
* Sometimes, it's not possible to register the key, when the Resident Key is required
* It seems it's related to Virtual authenticators provided by Selenium framework
* Manual testing with Google Chrome authenticators works as expected

View file

@ -158,7 +158,7 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest {
// Register webauthn-passwordless credential (resident key)
// Register webauthn credential (non resident key)
// Assert 'Try another way' with security key on first step (before any form input)
// Assert 'Try another way' with passkey on first step (before any form input)
// Authenticate UsernamePassword + WebAuthn (non resident key)
// Authenticate Username + WebAuthnPasswordless (resident key)
// Authenticate IDLess (resident key)
@ -265,7 +265,7 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest {
assertThat(selectAuthenticatorPage.getLoginMethodHelpText(SelectAuthenticatorPage.USERNAME),
is("Start sign in by entering your username"));
assertThat(selectAuthenticatorPage.getLoginMethodHelpText(SelectAuthenticatorPage.SECURITY_KEY),
is("Use your security key for passwordless sign in."));
is("Use your Passkey for passwordless sign in."));
selectAuthenticatorPage.selectLoginMethod(SelectAuthenticatorPage.USERNAMEPASSWORD);
loginPage.assertCurrent();
loginPage.clickTryAnotherWayLink();
@ -375,7 +375,7 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest {
}
else {
loginPage.assertCurrent();
assertThat(loginPage.getError(), containsString("Failed to authenticate by the Security key."));
assertThat(loginPage.getError(), containsString("Failed to authenticate by the Passkey."));
}
}

View file

@ -101,7 +101,7 @@ public class WebAuthnPropertyTest extends AbstractWebAuthnVirtualTest {
authenticateDefaultUser(false);
WaitUtils.pause((TIMEOUT + 2) * 1000);
webAuthnErrorPage.assertCurrent();
assertThat(webAuthnErrorPage.getError(), containsString("Failed to authenticate by the Security key."));
assertThat(webAuthnErrorPage.getError(), containsString("Failed to authenticate by the Passkey."));
}
}

View file

@ -262,7 +262,7 @@ public class WebAuthnRegisterAndLoginTest extends AbstractWebAuthnVirtualTest {
.client("account")
.assertEvent();
// Password + WebAuthn security key
// Password + WebAuthn Passkey
loginUsernamePage.open();
loginUsernamePage.assertCurrent();
loginUsernamePage.login("test-user@localhost");
@ -291,7 +291,7 @@ public class WebAuthnRegisterAndLoginTest extends AbstractWebAuthnVirtualTest {
selectAuthenticatorPage.assertCurrent();
assertThat(selectAuthenticatorPage.getLoginMethodHelpText(SelectAuthenticatorPage.SECURITY_KEY),
is("Use your security key for passwordless sign in."));
is("Use your Passkey for passwordless sign in."));
selectAuthenticatorPage.selectLoginMethod(SelectAuthenticatorPage.SECURITY_KEY);
webAuthnLoginPage.assertCurrent();

View file

@ -82,7 +82,7 @@ public class WebAuthnErrorTest extends AbstractWebAuthnAccountTest {
WaitUtils.pause((timeoutSec + 1) * 1000);
webAuthnErrorPage.assertCurrent();
assertThat(webAuthnErrorPage.getError(), is("Failed to authenticate by the Security key."));
assertThat(webAuthnErrorPage.getError(), is("Failed to authenticate by the Passkey."));
}
}
}

View file

@ -409,11 +409,11 @@ public class WebAuthnSigningInTest extends AbstractWebAuthnAccountTest {
if (passwordless) {
credentialType = webAuthnPwdlessCredentialType;
expectedHelpText = "Use your security key for passwordless sign in.";
expectedHelpText = "Use your Passkey for passwordless sign in.";
providerId = WebAuthnPasswordlessRegisterFactory.PROVIDER_ID;
} else {
credentialType = webAuthnCredentialType;
expectedHelpText = "Use your security key to sign in.";
expectedHelpText = "Use your Passkey to sign in.";
providerId = WebAuthnRegisterFactory.PROVIDER_ID;
}
@ -421,7 +421,7 @@ public class WebAuthnSigningInTest extends AbstractWebAuthnAccountTest {
// no way to simulate registration cancellation
assertThat("Set up link for \"" + credentialType.getType() + "\" is not visible", credentialType.isSetUpLinkVisible(), is(true));
assertThat(credentialType.getTitle(), is("Security key"));
assertThat(credentialType.getTitle(), is("Passkey"));
assertThat(credentialType.getHelpText(), is(expectedHelpText));
final String label1 = "WebAuthn is convenient";

View file

@ -473,25 +473,25 @@ recovery-codes-download-file-date=These codes were generated on
recovery-codes-label-default=Recovery codes
# WebAuthn
webauthn-display-name=Security Key
webauthn-help-text=Use your security key to sign in.
webauthn-passwordless-display-name=Security Key
webauthn-passwordless-help-text=Use your security key for passwordless sign in.
webauthn-login-title=Security Key login
webauthn-registration-title=Security Key Registration
webauthn-available-authenticators=Available Security Keys
webauthn-display-name=Passkey
webauthn-help-text=Use your Passkey to sign in.
webauthn-passwordless-display-name=Passkey
webauthn-passwordless-help-text=Use your Passkey for passwordless sign in.
webauthn-login-title=Passkey login
webauthn-registration-title=Passkey Registration
webauthn-available-authenticators=Available Passkeys
webauthn-unsupported-browser-text=WebAuthn is not supported by this browser. Try another one or contact your administrator.
webauthn-doAuthenticate=Sign in with Security Key
webauthn-doAuthenticate=Sign in with Passkey
webauthn-createdAt-label=Created
# WebAuthn Error
webauthn-error-title=Security Key Error
webauthn-error-registration=Failed to register your Security key.<br/> {0}
webauthn-error-api-get=Failed to authenticate by the Security key.<br/> {0}
webauthn-error-different-user=First authenticated user is not the one authenticated by the Security key.
webauthn-error-auth-verification=Security key authentication result is invalid.<br/> {0}
webauthn-error-register-verification=Security key registration result is invalid.<br/> {0}
webauthn-error-user-not-found=Unknown user authenticated by the Security key.
webauthn-error-title=Passkey Error
webauthn-error-registration=Failed to register your Passkey.<br/> {0}
webauthn-error-api-get=Failed to authenticate by the Passkey.<br/> {0}
webauthn-error-different-user=First authenticated user is not the one authenticated by the Passkey.
webauthn-error-auth-verification=Passkey authentication result is invalid.<br/> {0}
webauthn-error-register-verification=Passkey registration result is invalid.<br/> {0}
webauthn-error-user-not-found=Unknown user authenticated by the Passkey.
# Identity provider
identity-provider-redirector=Connect with another Identity Provider

View file

@ -106,10 +106,10 @@ recovery-authn-codes-help-text=These codes can be used to regain your access in
recovery-codes-number-used={0} recovery codes used
recovery-codes-number-remaining={0} recovery codes remaining
recovery-codes-generate-new-codes=Generate new codes to ensure access to your account
webauthn-display-name=Security key
webauthn-help-text=Use your security key to sign in.
webauthn-passwordless-display-name=Security key
webauthn-passwordless-help-text=Use your security key for passwordless sign in.
webauthn-display-name=Passkey
webauthn-help-text=Use your Passkey to sign in.
webauthn-passwordless-display-name=Passkey
webauthn-passwordless-help-text=Use your Passkey for passwordless sign in.
basic-authentication=Basic authentication
invalidRequestMessage=Invalid request