Documentation changes for the 2FA additions
Closes #40001 Signed-off-by: rmartinc <rmartinc@redhat.com>
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 36 KiB |
@ -114,13 +114,15 @@ The section presents some examples of conditional workflows that integrates 2nd
|
||||
|
||||
===== Conditional 2FA sub-flow
|
||||
|
||||
The default `browser` flow uses a `Conditional OTP` sub-flow that already gives a 2FA with OTP Form (One Time Password). Following the same idea, different 2FA methods can be integrated with the `Condition - User Configured`.
|
||||
The default `browser` flow uses a `Conditional 2FA` sub-flow that already gives 2nd factor Authentication (2FA) with OTP Form (One Time Password). It also provides WebAuthn and Recovery Codes but they are disabled by default. Consistent with this approach, different 2FA methods can be integrated with the `Condition - User Configured`.
|
||||
|
||||
.2FA all alternative
|
||||
image:images/2fa-example1.png[2FA all alternative]
|
||||
|
||||
The `forms` sub-flow contains another `2FA` conditional sub-flow with `Condition - user configured`. Three 2FA steps (OTP, Webauthn and Recovery Codes) are allowed as alternative steps. The user will be able to choose one of the three options, if they are configured for the user. As the sub-flow is conditional, the authentication process will complete successfully if no 2FA credential is configured.
|
||||
|
||||
This configuration provides the same behavior as when you configure with the default *browser* flow with both _Disabled_ steps are configured to _Alternative_.
|
||||
|
||||
===== Conditional 2FA sub-flow and deny access
|
||||
|
||||
The second example continues the previous one. After the `2FA` sub-flow, another flow `Deny access if no 2FA` is used to check if the previous `2FA` was not executed. In that case (the user has no 2FA credential configured) the access is denied.
|
||||
|
||||
@ -36,11 +36,13 @@ Since this sub-flow is marked as _alternative_, it will not be executed if the *
|
||||
|
||||
The first execution is the *Username Password Form*, an authentication type that renders the username and password page. It is marked as _required_, so the user must enter a valid username and password.
|
||||
|
||||
The second execution is the *Browser - Conditional OTP* sub-flow. This sub-flow is _conditional_ and executes depending on the result of the *Condition - User Configured* execution. If the result is true, {project_name} loads the executions for this sub-flow and processes them.
|
||||
The second execution is the *Browser - Conditional 2FA* sub-flow. This sub-flow is _conditional_ and executes depending on the result of the *Condition - User Configured* execution. If the result is true, {project_name} loads the executions for this sub-flow and processes them.
|
||||
|
||||
The next execution is the *Condition - User Configured* authentication. This authentication checks if {project_name} has configured other executions in the flow for the user. The *Browser - Conditional OTP* sub-flow executes only when the user has a configured OTP credential.
|
||||
The next execution is the *Condition - User Configured* authentication. This authentication checks if {project_name} has configured other executions in the flow for the user. The *Browser - Conditional 2FA* sub-flow executes only when the user has a configured OTP credential.
|
||||
|
||||
The final execution is the *OTP Form*. {project_name} marks this execution as _required_ but it runs only when the user has an OTP credential set up because of the setup in the _conditional_ sub-flow. If not, the user does not see an OTP form.
|
||||
The final execution is the *OTP Form*. {project_name} marks this execution as _alternative_, but it runs only when the user has an OTP credential set up because of the setup in the _conditional_ sub-flow. If the OTP credential is not set up, the user does not see an OTP form.
|
||||
|
||||
The default *browser* flow contains two more executions inside the *Browser - Conditional 2FA*, *WebAuthn Authenticator* and *Recovery Authentication Code Form*. These executions are _Disabled_ by default and they are the other 2FA methods that can be added to the flow. Change the requirement from _Disabled_ to _Alternative_ to make them available if the respective credential has been configured for the user. If the user has configured all alternative credential types, the credential with the highest priority is displayed by default. However, the *Try Another Way* option will appear so that the user has the alternative methods to log in.
|
||||
|
||||
===== Requirement
|
||||
A set of radio buttons that control the execution of an action executes.
|
||||
|
||||
@ -6,7 +6,7 @@ The Recovery Codes are a number of sequential one-time passwords (currently 12)
|
||||
|
||||
Due to its nature, the Recovery Codes work normally as a backup for another 2FA methods. They can complement the `OTP Form` or the `WebAuthn Authenticator` to give a backing way to log inside {project_name}, for example, if the software or hardware device used for the previous 2FA methods is broken or unavailable.
|
||||
|
||||
==== Enable Recovery Codes required action
|
||||
==== Check Recovery Codes required action is enabled
|
||||
|
||||
Check the Recovery Codes action is enabled in {project_name}:
|
||||
|
||||
@ -31,24 +31,13 @@ The following procedure adds the `Recovery Authentication Code Form` as an alter
|
||||
|
||||
. Click *Authentication* in the realm menu.
|
||||
. Click the *Browser* flow.
|
||||
. Select *Duplicate* from the *Action list* to make a copy of the built-in *Browser* flow.
|
||||
+
|
||||
For example enter *Recovery Codes Browser* as the name of the copy.
|
||||
. Click *Duplicate*.
|
||||
. In the flow *Recovery Codes Browser Browser - Conditional OTP*, click the *Add* (*+*) button and select *Add Execution*.
|
||||
. Filter to find the *Recovery Authentication Code Form* and *Add* the execution.
|
||||
. Set requirement to *Alternative* for the new step.
|
||||
. Set requirement to *Alternative* for the *OTP Form* too.
|
||||
. Locate the execution *Recovery Authentication Code Form* inside the *Browser - Conditional 2FA* sub-flow.
|
||||
. Change the _requirement_ from _Disabled_ to _Alternative_ for that execution.
|
||||
+
|
||||
.Recovery Codes Browser flow
|
||||
image:images/recovery-codes-browser-flow.png[Recovery Codes Browser flow]
|
||||
+
|
||||
. Click the *Action* menu at the top of the screen.
|
||||
. Select *Bind flow* from the drop-down list.
|
||||
. Select *Browser flow* from the drop-down list to setup this new flow as the default flow for the realm.
|
||||
. Click *Save*.
|
||||
|
||||
With this configuration, both 2FA authenticators (`OTP Form` and `Recovery Authentication Code Form`) are alternate ways to log into {project_name}. If the user has configured both credential types, the `OTP Form` will be displayed by default, but another option *Try Another Way* will be available that allows to select the *Recovery Authentication Code* to login.
|
||||
With this configuration, both 2FA authenticators (`OTP Form` and `Recovery Authentication Code Form`) are alternate ways to log into {project_name}. If the user has configured both credential types, the credential with the highest priority will be displayed by default, but the *Try Another Way* option will appear so that the user has the alternative methods to log in.
|
||||
|
||||
You can see more examples of 2FA configurations in <<twofa-conditional-workflow-examples>>.
|
||||
|
||||
|
||||
@ -19,71 +19,45 @@ WebAuthn's specification uses a `user.id` to map a public key credential to a sp
|
||||
The setup procedure of WebAuthn support for 2FA is the following:
|
||||
|
||||
[[_webauthn-register]]
|
||||
===== Enable WebAuthn authenticator registration
|
||||
===== Check WebAuthn authenticator registration is enabled
|
||||
|
||||
. Click *Authentication* in the menu.
|
||||
. Click the *Required Actions* tab.
|
||||
. Toggle the *Webauthn Register* switch to *ON*.
|
||||
. Check action *Webauthn Register* switch is set to *ON*.
|
||||
|
||||
Toggle the *Default Action* switch to *ON* if you want all new users to be required to register their WebAuthn credentials.
|
||||
|
||||
[[_webauthn-authenticator-setup]]
|
||||
==== Adding WebAuthn authentication to a browser flow
|
||||
==== Enable WebAuthn authentication in the default browser flow
|
||||
|
||||
. Click *Authentication* in the menu.
|
||||
. Click the *Browser* flow.
|
||||
. Select *Duplicate* from the "Action list" to make a copy of the built-in *Browser* flow.
|
||||
. Enter "WebAuthn Browser" as the name of the copy.
|
||||
. Click *Duplicate*.
|
||||
. Click the name to go to the details
|
||||
. Click the trash can icon 🗑️ of the "WebAuthn Browser Browser - Conditional OTP" and click *Delete*.
|
||||
|
||||
If you require WebAuthn for all users:
|
||||
|
||||
. Click *+* menu of the *WebAuthn Browser Forms*.
|
||||
. Click *Add step*.
|
||||
. Click *WebAuthn Authenticator*.
|
||||
. Click *Add*.
|
||||
. Select *Required* for the *WebAuthn Authenticator* authentication type to set its requirement to required.
|
||||
. Locate the execution *WebAuthn Authenticator* inside the *Browser - Conditional 2FA* sub-flow.
|
||||
. Change the _requirement_ from _Disabled_ to _Alternative_ for that execution.
|
||||
+
|
||||
image:images/webauthn-browser-flow-required.png[Webauthn browser flow required]
|
||||
+
|
||||
. Click the *Action* menu at the top of the screen.
|
||||
. Select *Bind flow* from the drop-down list.
|
||||
. Select *Browser* from the drop-down list.
|
||||
. Click *Save*.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
If a user does not have WebAuthn credentials, the user must register WebAuthn credentials.
|
||||
====
|
||||
|
||||
Users can log in with WebAuthn if they have a WebAuthn credential registered only. So instead of adding the *WebAuthn Authenticator* execution, you can:
|
||||
|
||||
.Procedure
|
||||
. Click *+* menu of the *WebAuthn Browser Forms* row.
|
||||
. Click *Add sub-flow*.
|
||||
. Enter "Conditional 2FA" for the _name_ field.
|
||||
. Select *Conditional* for the *Conditional 2FA* to set its requirement to conditional.
|
||||
. On the *Conditional 2FA* row, click the plus sign + and select *Add condition*.
|
||||
. Click *Add condition*.
|
||||
. Select *Condition - User Configured*.
|
||||
. Click *Add*.
|
||||
. Select *Required* for the *Condition - User Configured* to set its requirement to required.
|
||||
. Drag and drop *WebAuthn Authenticator* into the *Conditional 2FA* flow
|
||||
. Select *Alternative* for the *WebAuthn Authenticator* to set its requirement to alternative.
|
||||
.WebAuthn browser flow conditional with OTP
|
||||
image:images/webauthn-browser-flow-conditional-with-OTP.png[WebAuthn browser flow conditional with OTP]
|
||||
|
||||
With this configuration, the users can choose between using WebAuthn and OTP for the second factor. As the sub-flow is _conditional_, they are only asked to present a 2FA credential (OTP or WebAuthn) if they have already registered one of the respective credential types. If a user has configured both credential types, the credential with the highest priority will be displayed by default. However, the *Try Another Way* option will appear so that the user has the alternative methods to log in.
|
||||
|
||||
If you want to substitute OTP for WebAuthn and maintain it as conditional:
|
||||
|
||||
. Change _requirement_ in *OTP Form* to _Disabled_.
|
||||
. Change _requirement_ in *WebAuthn Authenticator* to _Alternative_.
|
||||
+
|
||||
.Webauthn browser flow conditional
|
||||
image:images/webauthn-browser-flow-conditional.png[Webauthn browser flow conditional]
|
||||
|
||||
The user can choose between using WebAuthn and OTP for the second factor:
|
||||
If you require WebAuthn for all users and enforce them to configure the credential if not configured:
|
||||
|
||||
.Procedure
|
||||
. On the *Conditional 2FA* row, click the plus sign + and select *Add step*.
|
||||
. Select *OTP Form* from the list.
|
||||
. Click *Add*.
|
||||
. Select *Alternative* for the *OTP Form* to set its requirement to alternative.
|
||||
. Change _requirement_ in *Browser - Conditional 2FA* to _Required_.
|
||||
. Change _requirement_ in *OTP Form* to _Disabled_.
|
||||
. Change _requirement_ in *WebAuthn Authenticator* to _Required_.
|
||||
+
|
||||
image:images/webauthn-browser-flow-conditional-with-OTP.png[WebAuthn browser flow conditional with OTP]
|
||||
.Webauthn browser flow required
|
||||
image:images/webauthn-browser-flow-required.png[Webauthn browser flow required]
|
||||
|
||||
You can see more examples of 2FA configurations in <<twofa-conditional-workflow-examples>>.
|
||||
|
||||
==== Authenticate with WebAuthn authenticator
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ Cookie - ALTERNATIVE
|
||||
Kerberos - ALTERNATIVE
|
||||
Forms subflow - ALTERNATIVE
|
||||
Username/Password Form - REQUIRED
|
||||
Conditional OTP subflow - CONDITIONAL
|
||||
Conditional 2FA subflow - CONDITIONAL
|
||||
Condition - User Configured - REQUIRED
|
||||
OTP Form - REQUIRED
|
||||
----
|
||||
@ -115,14 +115,14 @@ Let's walk through the steps from when a client first redirects to keycloak to a
|
||||
A failureChallenge() means that there is a challenge, but that the flow should log this as an error in the error log.
|
||||
This error log can be used to lock accounts or IP Addresses that have had too many login failures.
|
||||
If the username and password is valid, the provider associated the UserModel with the AuthenticationSessionModel and returns a status of success().
|
||||
. The next execution is a subflow called Conditional OTP. The executions for this subflow are loaded and the same processing logic occurs. Its Requirement is
|
||||
. The next execution is a subflow called Conditional 2FA. The executions for this subflow are loaded and the same processing logic occurs. Its Requirement is
|
||||
Conditional. This means that the flow will first evaluate all conditional executors that it contains. Conditional executors are authenticators that
|
||||
implement `ConditionalAuthenticator`, and must implement the method `boolean matchCondition(AuthenticationFlowContext context)`. A conditional subflow will
|
||||
call the `matchCondition` method of all conditional executions it contains, and if all of them evaluate to true, it will act as if it was a required subflow. If
|
||||
not, it will act as if it was a disabled subflow. Conditional authenticators are only used for this purpose, and are not used as authenticators.
|
||||
This means that even if the conditional authenticator evaluates to "true", then this will not mark a flow or subflow as successful. For example,
|
||||
a flow containing only a Conditional subflow with only a conditional authenticator will never allow a user to log in.
|
||||
. The first execution of the Conditional OTP subflow is the Condition - User Configured.
|
||||
. The first execution of the Conditional 2FA subflow is the Condition - User Configured.
|
||||
This provider requires that a user has been associated with the flow.
|
||||
This requirement is satisfied because the UsernamePassword provider already associated the user with the flow.
|
||||
This provider's `matchCondition` method will evaluate the `configuredFor` method for all other Authenticators in its current subflow. If the subflow contains
|
||||
@ -134,7 +134,7 @@ Let's walk through the steps from when a client first redirects to keycloak to a
|
||||
Since a user is required for this provider, the provider is also asked if the user is configured to use this provider.
|
||||
If user is not configured, then the flow will then set up a required action that the user must perform after authentication is complete.
|
||||
For OTP, this means the OTP setup page. If the user is configured, he will be asked to enter his otp code. In our scenario, because of the conditional
|
||||
sub-flow, the user will never see the OTP login page, unless the Conditional OTP subflow is set to Required.
|
||||
sub-flow, the user will never see the OTP login page, unless the Conditional 2FA subflow is set to Required.
|
||||
. After the flow is complete, the authentication processor creates a UserSessionModel and associates it with the AuthenticationSessionModel.
|
||||
It then checks to see if the user is required to complete any required actions before logging in.
|
||||
. First, each required action's evaluateTriggers() method is called.
|
||||
|
||||
@ -148,3 +148,8 @@ The new procedure recommends to re-apply any changes to `cache-ispn.xml` or a cu
|
||||
|
||||
This prevents accidentally downgrading functionality, for example, by using an old `cache-ispn.xml` file from a previous version.
|
||||
|
||||
=== Default browser flow changes 2FA to include WebAuthn and Recovery Codes
|
||||
|
||||
Previously the default *browser* flow had a *Browser - Conditional OTP* conditional sub-flow that enabled One-Time Password (OTP) as a 2nd Factor Authentication (2FA). Starting with this version, the sub-flow is renamed to *Browser - Conditional 2FA*, the *OTP Form* is _Alternative_, and includes two more 2FA methods: *WebAuthn Authenticator* and *Recovery Authentication Code Form*. Both new executions are _Disabled_ by default, but they can be set to _Alternative_ to include them into the flow.
|
||||
|
||||
Upgraded realms will not be changed. The updated flow will only be available for new realms. Take this change into consideration if you have automated the realm creation.
|
||||