Class AuthService
This class presents an basic authentication service, which offers authentication functionality that is not specific to an authentication mechanism (such as password authentication or OAuth authentication).
Like all service classes, this class holds only configuration state. Thus, once configured, it can be safely shared between multiple sessions since its state (the configuration) is read-only.
The class provides the following services (and relevant configuration):
- settings for generating random tokens:
- authentication tokens, used by e.g. remember-me functionality:
- email tokens, for email verification and lost password functions:
- MFA tokens, used by multi-factor authentication functionality:
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptioncreateAuthToken
(User user) Creates and stores an authentication token for the user.protected String
createRedirectUrl
(String token) Returns the authentication token cookie domain.Returns the authentication token cookie name.int
Returns the authentication token validity.Returns the internal path used for email tokens.int
Returns the duration for an email token to remain valid.Returns the identity policy.int
Returns the length of the expected MFA codes.Returns the provider that manages the MFA step.Returns the MFA token cookie domain.Returns the name of the MFA "remember-me" cookie.int
Returns the validity span of the MFA "remember-me" cookie.int
Returns the token length.Returns the token hash function.identifyUser
(Identity identity, AbstractUserDatabase users) Tries to match the identity to an existing user.boolean
Returns whether authentication tokens are enabled.boolean
Returns whether the auth token is updated.boolean
Returns whether email verification is configured.boolean
\ Returns whether email verification is required for login.boolean
Returns whether a second factor is enabled when logging in.boolean
Returns whether multiple factors are required when logging in.boolean
Returns if throttling is enabled during the MFA process.void
lostPassword
(String emailAddress, AbstractUserDatabase users) Implements lost password functionality.parseEmailToken
(String internalPath) Parses the emailtoken from an internal path.processAuthToken
(String token, AbstractUserDatabase users) Processes an authentication token.processEmailToken
(String token, AbstractUserDatabase users) Processes an email token.protected void
sendConfirmMail
(String address, User user, String token) Sends a confirmation email to the user to verify his email address.protected void
sendLostPasswordMail
(String address, User user, String token) Sends an email to the user to enter a new password.void
sendMail
(javax.mail.Message message) Sends an email.final void
setAuthTokensEnabled
(boolean enabled) Configures authentication token support.final void
setAuthTokensEnabled
(boolean enabled, String cookieName) Configures authentication token support.void
setAuthTokensEnabled
(boolean enabled, String cookieName, String cookieDomain) Configures authentication token support.void
setAuthTokenUpdateEnabled
(boolean enabled) Set whetherprocessAuthToken()
updates the auth token.void
setAuthTokenValidity
(int minutes) Configures the duration for an authenticaton to remain valid.void
setEmailRedirectInternalPath
(String internalPath) Sets the internal path used to present tokens in emails.void
setEmailTokenValidity
(int minutes) Configures the duration for an email token to remain valid.void
setEmailVerificationEnabled
(boolean enabled) Configures email verification.void
setEmailVerificationRequired
(boolean enabled) Configure email verificiation to be required for login.void
setIdentityPolicy
(IdentityPolicy identityPolicy) Configures the identity policy.void
setMfaCodeLength
(int length) Sets the length of the code that is expected for MFA.void
setMfaProvider
(String provider) Sets whether multiple factors are enabled when logging in.void
setMfaRequired
(boolean require) Sets whether multiple factors are required when logging in.void
setMfaThrottleEnabled
(boolean enabled) Sets whether throttling is enabled during the MFA process.void
setMfaTokenCookieDomain
(String domain) Returns the domain of the MFA "remember-me" cookie.void
setMfaTokenCookieName
(String name) Sets the name of the cookie used for MFA "remember-me".void
setMfaTokenValidity
(int validity) Sets the validity duration of the MFA "remember-me" cookie.void
setRandomTokenLength
(int length) Sets the token length.void
setTokenHashFunction
(HashFunction function) Sets the token hash function.void
verifyEmailAddress
(User user, String address) Verifies an email address.
-
Constructor Details
-
AuthService
public AuthService()Constructor.
-
-
Method Details
-
setRandomTokenLength
public void setRandomTokenLength(int length) Sets the token length.Configures the length used for random tokens. Random tokens are generated for authentication tokens, and email tokens.
The default length is 32 characters.
-
getRandomTokenLength
public int getRandomTokenLength()Returns the token length.- See Also:
-
setIdentityPolicy
Configures the identity policy.The identity policy has an impact on the login and registration procedure.
-
getIdentityPolicy
Returns the identity policy. -
identifyUser
Tries to match the identity to an existing user.When authenticating using a 3rd party
Identity
Provider, the identity is matched against the existing users, based on the id (withAbstractUserDatabase#findWithIdentity()
), or if not matched, based on whether there is a user with the same verified email address as the one indicated by the identity. -
setAuthTokensEnabled
Configures authentication token support.This method allows you to configure whether authentication tokens are in use. Authentication tokens are used for the user to bypass a more elaborate authentication method, and are a secret shared with the user's user agent, usually in a cookie. They are typically presented in the user interfaces as a "remember me" option.
Whenever a valid authentication token is presented in processToken(), it is invalidated a new token is generated and stored for the user.
The tokens are generated and subsequently hashed using the token hash function. Only the hash values are stored in the user database so that a compromised user database does not compromise these tokens.
Authentication tokens are disabled by default.
The default name for these cookies is
wtauth
, and if MFA is enabled, their corresponding name will bewtauth-mfa
. The name of these tokens can be changed (setMfaTokenCookieName()
). -
setAuthTokensEnabled
public final void setAuthTokensEnabled(boolean enabled) Configures authentication token support. -
setAuthTokensEnabled
Configures authentication token support. -
isAuthTokensEnabled
public boolean isAuthTokensEnabled()Returns whether authentication tokens are enabled. -
setAuthTokenUpdateEnabled
public void setAuthTokenUpdateEnabled(boolean enabled) Set whetherprocessAuthToken()
updates the auth token.If this option is enabled,
processAuthToken()
will replace the auth token with a new token. This is a bit more secure, because an auth token can only be used once. This is enabled by default.However, this means that if a user concurrently opens multiple sessions within the same browsers (e.g. multiple tabs being restored at the same time) or refreshes before they receive the new cookie, the user will be logged out, unless the
AbstractUserDatabase
implementation takes this into account (e.g. keeps the old token valid for a little bit longer)The default Dbo::UserDatabase does not handle concurrent token updates well, so disable this option if you want to prevent that issue.
Note: If using MFA,
processAuthToken()
will also use this functionality. -
isAuthTokenUpdateEnabled
public boolean isAuthTokenUpdateEnabled()Returns whether the auth token is updated. -
getAuthTokenCookieName
Returns the authentication token cookie name.This is the default cookie name used for storing the authentication token in the user's browser.
-
getAuthTokenCookieDomain
Returns the authentication token cookie domain.This is the domain used for the authentication cookie. By default this is empty, which means that a cookie will be set for this application.
You may want to set a more general domain if you are sharing the authentication with multiple applications.
-
setTokenHashFunction
Sets the token hash function.Sets the hash function used to safely store authentication tokens in the database. Ownership of the hash function is transferred.
The default token hash function is an
MD5HashFunction
. -
getTokenHashFunction
Returns the token hash function. -
createAuthToken
Creates and stores an authentication token for the user.This creates and stores a new authentication token for the given user.
The returned value is the token that may be used to re-identify the user in
processAuthToken()
. -
processAuthToken
Processes an authentication token.This verifies an authentication token, and considers whether it matches with a token hash value stored in database. This indicates that the cookie a
User
has in their browser is still valid, and can be used to uniquely identify them.If it matches and auth token update is enabled (
setAuthTokenUpdateEnabled()
), the token is updated with a new hash. -
setAuthTokenValidity
public void setAuthTokenValidity(int minutes) Configures the duration for an authenticaton to remain valid.The default duration is two weeks (14 * 24 * 60 minutes).
-
getAuthTokenValidity
public int getAuthTokenValidity()Returns the authentication token validity.- See Also:
-
setEmailVerificationEnabled
public void setEmailVerificationEnabled(boolean enabled) Configures email verification.Email verification is useful for a user to recover a lost password, or to be able to confidently confirm other events with this user (such as order processing).
-
isEmailVerificationEnabled
public boolean isEmailVerificationEnabled()Returns whether email verification is configured. -
setEmailVerificationRequired
public void setEmailVerificationRequired(boolean enabled) Configure email verificiation to be required for login.When enabled, a user will not be able to login if the email-address was not verified.
-
isEmailVerificationRequired
public boolean isEmailVerificationRequired()\ Returns whether email verification is required for login. -
setEmailRedirectInternalPath
Sets the internal path used to present tokens in emails.The default path is "/auth/mail/".
-
getEmailRedirectInternalPath
Returns the internal path used for email tokens. -
parseEmailToken
Parses the emailtoken from an internal path.This method parses an internal path and if it matches the email redirection path, it returns the token contained.
It returns an empty string if the internal path does not contain an email token.
-
verifyEmailAddress
public void verifyEmailAddress(User user, String address) throws javax.mail.MessagingException, UnsupportedEncodingException, IOException Verifies an email address.This registers a new email token with the user.
Then it sends an email to the user's unverified email address with instructions that redirect him to this site, using sendConfirmEmail().
- Throws:
javax.mail.MessagingException
UnsupportedEncodingException
IOException
- See Also:
-
lostPassword
public void lostPassword(String emailAddress, AbstractUserDatabase users) throws javax.mail.MessagingException, UnsupportedEncodingException, IOException Implements lost password functionality.If email address verification is enabled, then a user may recover his password (or rather, chose a new password) using a procedure which involves sending an email to a verified email address.
This method triggers this process, starting from an email address, if this email address corresponds to a verified email address in the database. The current password is not invalidated.
- Throws:
javax.mail.MessagingException
UnsupportedEncodingException
IOException
- See Also:
-
processEmailToken
Processes an email token.This processes a token received through an email. If it is an email verification token, the token is removed from the database.
This may return two successful results:
EmailTokenState.EmailConfirmed
: a token was presented which proves that the user is tied to the email address.EmailTokenState.UpdatePassword
: a token was presented which requires the user to enter a new password.
Note: Since JWt 4.3.0, the behavior of this function changed. The lost password token is no longer removed by
processEmailToken()
. Instead, it is now removed inUser#setPassword()
. -
setEmailTokenValidity
public void setEmailTokenValidity(int minutes) Configures the duration for an email token to remain valid.The default duration is three days (3 * 24 * 60 minutes). Three is a divine number.
-
getEmailTokenValidity
public int getEmailTokenValidity()Returns the duration for an email token to remain valid.- See Also:
-
sendMail
public void sendMail(javax.mail.Message message) throws javax.mail.MessagingException, UnsupportedEncodingException, IOException Sends an email.Sends an email to the given address with subject and body.
The default implementation will consult configuration properties to add a sender address if it hasn't already been set:
- "auth-mail-sender-name": the sender name, with default value "Wt Auth module"
- "auth-mail-sender-address": the sender email address, with default value "noreply-auth@www.webtoolkit.eu"
Then it uses the JavaMail API to send the message, the SMTP settings are configured using the smtp.host and smpt.port JWt configuration variables (see
Configuration.setProperties(HashMap properties)
).- Throws:
javax.mail.MessagingException
UnsupportedEncodingException
IOException
-
setMfaProvider
Sets whether multiple factors are enabled when logging in.If this is set to any value that isn't
empty
, a second factor (currently only TOTP as a default implementation) will be enabled. Instead of logging theUser
in with theLoginState.Strong
(when authenticating with a password), the state will be set toLoginState.RequiresMfa
.This indicates that the user is still required to provide an additional login step. This applied to the regular login only.
Login
via OAuth does not make use of MFA. The authenticator should be sufficiently secure in itself, and should be trusted.By default JWt offers TOTP (Time-based One-time password) as a second factor. This is a code that any authenticator app/extension can generate.
By default this feature is disabled.
Note: If a value for a
provider
is set here, MFA will be enabled. This will use TOTP by default. Any custom implementation (usingAbstractMfaProcess
) will require more changes. -
getMfaProvider
Returns the provider that manages the MFA step.- See Also:
-
isMfaEnabled
public boolean isMfaEnabled()Returns whether a second factor is enabled when logging in.This marks that users can enable the MFA feature. This can be any implemenation of the
AbstractMfaProcess
interface. JWt supplies a single default implementation, namelyTotpProcess
.For the default JWt implementation, this means that developers can generate a TOTP secret key (Mfa::generateSecretKey()) which can be used for MFA, by means of the
TotpProcess
.- See Also:
-
setMfaRequired
public void setMfaRequired(boolean require) Sets whether multiple factors are required when logging in.If this is set to
true
, a second factor (defaulting to TOTP) will be required on login. Instead of logging theUser
in with theLoginState.Strong
(when authenticating with a password), the state will be set toLoginState.RequiresMfa
.This will only take effect is
isMfaEnabled()
istrue
as well (and thus if an MFA provider has been configured (setMfaProvider()
). If this is the case, all users will be enforced to verify their login with an extra step, for more security.By JWt's default implementation this will boil down to providing a TOTP code. Either this will be the first time they do this. In which case they will be given the secret key both in QR code format (using Mfa::AbstractMfaWidgget::createSetupView()), and as a string. When they enter a correct generated code, the secret will be attached to the
User
record as anIdentity
, and will be used for subsequent login attempts (usingAbstractMfaProcess.createInputView()
). -
isMfaRequired
public boolean isMfaRequired()Returns whether multiple factors are required when logging in.This marks that the MFA feature is enforced for all users.
For JWt's default implementation this means that upon logging in they will have to provide a TOTP code for verification.
- See Also:
-
setMfaCodeLength
public void setMfaCodeLength(int length) Sets the length of the code that is expected for MFA.This function does not make sense for all implementations of MFA.
Currently JWt ships with a TOTP implementation, in which case the code can be any length in the range [6-16]. Of course longer is "better" generally speaking.
By default the length is
6
.Note: Due to the TOTP algorithm a longer code may not always make too much sense, as the code can start with a lot of leading zeroes. Generally a length of
6
is most often seen. -
getMfaCodeLength
public int getMfaCodeLength()Returns the length of the expected MFA codes.- See Also:
-
setMfaTokenCookieName
Sets the name of the cookie used for MFA "remember-me".This name can be changed to any name the developer desires, that is a valid name for a cookie. By default this name is the same name as
getAuthTokenCookieName()
with "-mfa" appended. If this name is not changed from the default, this will result in the "wtauth-mfa" name.Note: No check is performed for clashing names, so this can potentially override existing cookies.
-
getMfaTokenCookieName
Returns the name of the MFA "remember-me" cookie.This can be configured by the developer, or otherwise uses the same name as
getAuthTokenCookieName()
with the "-mfa" suffix. If nothing is changed, the default is "wtauth-mfa". -
setMfaTokenCookieDomain
Returns the domain of the MFA "remember-me" cookie.This can be configured by the developer, or otherwise uses the same name as
getAuthTokenCookieDomain()
. If nothing is changed, the default is an empty string.This should best be used if multiple applications are living on the same
-
getMfaTokenCookieDomain
Returns the MFA token cookie domain.- See Also:
-
setMfaTokenValidity
public void setMfaTokenValidity(int validity) Sets the validity duration of the MFA "remember-me" cookie.The duration is specified in minutes. So a validity of 1440 will keep the cookie valid for a whole day. This ensures that there is a limit on how long the
User
's MFA verification can be bypassed.From a security aspect, this value should be kept on the lower side so that a user will be required to demonstrate a TOTP code often to the application, by which they validate their identity.
-
getMfaTokenValidity
public int getMfaTokenValidity()Returns the validity span of the MFA "remember-me" cookie.- See Also:
-
setMfaThrottleEnabled
public void setMfaThrottleEnabled(boolean enabled) Sets whether throttling is enabled during the MFA process.By default this is not enabled.
- See Also:
-
isMfaThrottleEnabled
public boolean isMfaThrottleEnabled()Returns if throttling is enabled during the MFA process.- See Also:
-
sendConfirmMail
protected void sendConfirmMail(String address, User user, String token) throws javax.mail.MessagingException, UnsupportedEncodingException, IOException Sends a confirmation email to the user to verify his email address.Sends a confirmation email to the given address.
The email content is provided by the following string keys:
- subject: tr("Wt.auth.verification-mail.subject")
- body: tr("Wt.auth.verification-mail.body") with {1} a place holder for the identity, and {2} a placeholder for the redirection URL.
- HTML body: tr("Wt.auth.verification-mail.htmlbody") with the same place holders.
- Throws:
javax.mail.MessagingException
UnsupportedEncodingException
IOException
-
sendLostPasswordMail
protected void sendLostPasswordMail(String address, User user, String token) throws javax.mail.MessagingException, UnsupportedEncodingException, IOException Sends an email to the user to enter a new password.This sends a lost password email to the given
address
, with a giventoken
.The default implementation will call
sendMail()
with the following message:- tr("Wt.Auth.lost-password-mail.subject") as subject,
- tr("Wt.Auth.lost-password-mail.body") as body to which it passes user.identity() and token as arguments.
- tr("Wt.Auth.lost-password-mail.htmlbody") as HTML body to which it passes user.identity() and token as arguments.
- Throws:
javax.mail.MessagingException
UnsupportedEncodingException
IOException
-
createRedirectUrl
-