Wt
4.11.0
|
The interface for a second factor authentication process. More...
#include <Wt/Auth/Mfa/AbstractMfaProcess.h>
Public Member Functions | |
AbstractMfaProcess (const AuthService &authService, AbstractUserDatabase &users, Login &login) | |
Constructor. | |
virtual const std::string & | provider () const |
Returns the name of the provider for the process. | |
virtual void | processEnvironment () |
Processes the (initial) environment. | |
virtual std::unique_ptr< WWidget > | createSetupView ()=0 |
Creates the view that displays the MFA configuration step. | |
virtual std::unique_ptr< WWidget > | createInputView ()=0 |
Creates the view that displays the MFA input step. | |
void | setMfaThrottle (std::unique_ptr< AuthThrottle > authThrottle) |
Sets the instance that manages throttling. | |
Public Member Functions inherited from Wt::WObject | |
void | addChild (std::unique_ptr< WObject > child) |
Add a child WObject whose lifetime is determined by this WObject. | |
template<typename Child > | |
Child * | addChild (std::unique_ptr< Child > child) |
Add a child WObject, returning a raw pointer. | |
std::unique_ptr< WObject > | removeChild (WObject *child) |
Remove a child WObject, so its lifetime is no longer determined by this WObject. | |
template<typename Child > | |
std::unique_ptr< Child > | removeChild (Child *child) |
Remove a child WObject, so its lifetime is no longer determined by this WObject. | |
virtual const std::string | id () const |
Returns the (unique) identifier for this object. | |
virtual void | setObjectName (const std::string &name) |
Sets an object name. | |
virtual std::string | objectName () const |
Returns the object name. | |
void | resetLearnedSlots () |
Resets learned stateless slot implementations. | |
template<class T > | |
void | resetLearnedSlot (void(T::*method)()) |
Resets a learned stateless slot implementation. | |
template<class T > | |
WStatelessSlot * | implementStateless (void(T::*method)()) |
Declares a slot to be stateless and learn client-side behaviour on first invocation. | |
template<class T > | |
WStatelessSlot * | implementStateless (void(T::*method)(), void(T::*undoMethod)()) |
Declares a slot to be stateless and learn client-side behaviour in advance. | |
void | isNotStateless () |
Marks the current function as not stateless. | |
template<class T > | |
WStatelessSlot * | implementJavaScript (void(T::*method)(), const std::string &jsCode) |
Provides a JavaScript implementation for a method. | |
Public Member Functions inherited from Wt::Core::observable | |
observable () noexcept | |
Default constructor. | |
virtual | ~observable () |
Destructor. | |
template<typename... Args, typename C > | |
auto | bindSafe (void(C::*method)(Args...)) noexcept |
Protects a method call against object destruction. | |
template<typename... Args, typename C > | |
auto | bindSafe (void(C::*method)(Args...) const) const noexcept |
Protects a const method call against object destruction. | |
template<typename Function > | |
auto | bindSafe (const Function &function) noexcept |
Protects a function against object destruction. | |
Protected Member Functions | |
virtual Wt::WString | userIdentity () |
Retrieves the current User's identity for the provider. | |
virtual bool | createUserIdentity (const Wt::WString &identityValue) |
Adds an Identity to the current User with the given value. | |
virtual User | processMfaToken () |
Processes an MFA authentication token. | |
virtual void | setRememberMeCookie (User user) |
Creates an MFA authentication token. | |
virtual void | configureThrottling (WInteractWidget *button) |
Configures client-side throttling on the process. | |
virtual void | updateThrottling (WInteractWidget *button) |
Updates client-side login throttling on the process. | |
Protected Member Functions inherited from Wt::WObject | |
virtual WStatelessSlot * | getStateless (Method method) |
On-demand stateless slot implementation. | |
Additional Inherited Members | |
Public Types inherited from Wt::WObject | |
typedef void(WObject::* | Method) () |
Typedef for a WObject method without arguments. | |
The interface for a second factor authentication process.
This class defines the interface to be used when implementing a second factor in the authentication flow. Currently, it is strongly advised (by among others OWASP) that a second factor is added to any authentication module.
When a developer wishes to enable MFA they will need to set the AuthService::setMfaProvider(), and optionally AuthService::setMfaRequired(). This will enable Wt to display the MFA step to users logging into the system. This will be shown after a user:
The MFA step can be either the setup view, which holds the initial state for the MFA method. For Wt's default, this means a QR code with the TOTP secret encoded. This then adds an Identity to the user, by which they can be authenticated against a certain provider. The secret key is also displayed, so that it can be copied into a password manager or authenticator app.
For this to work, a developer needs to implement createSetupView(). The method creates the widget that displays the view. This view tells the user how to set up the MFA step. The default TotpProcess will bind the content to a template. But developers are free to use their own way (like showing a pop-up) This will require the developer to override the AuthWidget::createMfaView().
After this setup, the process can be repeated but a simpler view is often desired here, one that no longer hold any configuration state, but simply asks for a token of authentication. This is where createInputView() comes into play. This functions the exact same way as the above setup view counterpart, but shows less information. Again, for Wt's default implementation, using TOTP, this means a 6 (depending on configuration, see: AuthService::setMfaCodeLength()) digit code, that is generated from their secret key will be asked of the user. The initial (QR) code that serves as the way to generate the TOTP keys, will no longer be displayed.
A successful match of the second factor will then result in an actual login (Login::login()) (see the note).
To use your own widget in the normal authentication flow, one also needs to override AuthWidget::createMfaProcess(), so that it will create the correct widget. By default this will create the TotpProcess.
|
protectedvirtual |
Configures client-side throttling on the process.
If attempt throttling is enabled, then this may also be indicated client-side using JavaScript by disabling the login button and showing a count-down indicator. This method initializes this JavaScript utility function for a login button.
If throttling is enabled, it may be necessary for a custom implementation to manage this state itself. This is to allow developers the freedom to define their own MFA processes.
Look at TotpProcess::verifyCode() for an example.
|
pure virtual |
Creates the view that displays the MFA input step.
The user already has an identity attached to their record. This step now needs valid input from them to continue.
Implemented in Wt::Auth::Mfa::TotpProcess.
|
pure virtual |
Creates the view that displays the MFA configuration step.
This is the view that is shown to a user if they do not have MFA enabled yet. This will often show more information to them, telling them how the feature is to be used and activated.
The state of whether a user has MFA enabled or not can be decided in two ways:
true
) Implemented in Wt::Auth::Mfa::TotpProcess.
|
protectedvirtual |
Adds an Identity to the current User with the given value.
The identity will be created with the specified provider() on the process. And the actual identity will be identityValue
.
This is again a method that offers very basic functionality, calling: User::identity() and User::addIdentity(), with some logging added to it.
|
virtual |
Processes the (initial) environment.
This can be called to tell the widget to look through the environment for the relevent cookies. It will handle the side-effect of finding such a cookie, and it still being valid. The user will be logged in, in a weak state (LoginState::Weak), and the authenticated() signal will be fired, with an AuthenticationStatus::Success.
Reimplemented in Wt::Auth::Mfa::TotpProcess.
|
protectedvirtual |
Processes an MFA authentication token.
If a token is present in the browser, going by the name found in AuthService::mfaTokenCookieName(), and that is still valid (see AuthService::mfaTokenValidity()), the User can be retrieved from that token. This identifies the user uniquely, ensuring their MFA verification step can be skipped for a certain period.
|
virtual |
Returns the name of the provider for the process.
void Wt::Auth::Mfa::AbstractMfaProcess::setMfaThrottle | ( | std::unique_ptr< AuthThrottle > | authThrottle | ) |
Sets the instance that manages throttling.
Throtteling is an additional safety measure. It ensures that the MFA process cannot be brute-forced.
Setting the throttler, will allow for it to be configured (configureThrottling()), and updated (updateThrottling()) if applicable.
Creates an MFA authentication token.
A token (with the correct prefix for MFA) is created and persisted in the database. A cookie is created in the user's
browser. This token can later be used by processMfaToken() to identify the User, allowing them to skip the MFA step.
|
protectedvirtual |
Updates client-side login throttling on the process.
This should be called after a MFA authentication event takes place, if you want to reflect throttling using a client-side count-down indicator on the button.
You need to call configureThrottling() before you can do this.
If throttling is enabled, it may be necessary for a custom implementation to manage this state itself. This is to allow developers the freedom to define their own MFA processes.
Look at TotpProcess::verifyCode() for an example.
|
protectedvirtual |
Retrieves the current User's identity for the provider.
This is simply a method that retrieves the current User's identity, given the provider the process specified (see provider()). This can be accessed by calling User::identity() as well.
The method will return the identity, if it exists, or an empty string if it does not. It will also log (to "warn") in the latter case.