Two-Factor Authentication
When a user account requires two-factor authentication (2FA), the normal Bitwarden authentication flow is diverted in order to handle the 2FA request.
Initial authentication request
When the Identity API receives an authentication request for a user, part of the validation process is to ensure that the user's account does not require two-factor authentication.
If the account (or the user's organization) requires 2FA, the /connect/token
endpoint returns a
response with an HTTP status code 400
, an Error
value of invalid_grant
, and an ErrorMessage
of "Two factor required". The response will also include a CustomResponse
with the following
JSON data:
{
{ "TwoFactorProviders", [2FA provider keys] },
{ "TwoFactorProviders2", [2FA provider data] },
{ "MasterPasswordPolicy", [Master password policy] },
// Only if the user has email 2FA
{ "SsoEmail2faSessionToken", [Token to allow email to be passed through SSO flow] }
}
Handling 2FA response on the client
If the client detects a
IdentityTwoFactorResponse
when attempting to log in, it extracts the available 2FA providers from the CustomResponse
and
presents those to the user.
Each 2FA method has its own UI, but in all cases the user will generate a "token" of some sort to
capture the user's response. This token is captured on the
TwoFactorComponent
when the user completes the 2FA process.
Once the user has entered their 2FA, a new authentication request is POST
ed to the
/connect/token
endpoint with the same contents as the original, failed request, with the following
additions to the request body:
twoFactorToken
is set to the token generated by the user's 2FA responsetwoFactorProvider
is set to the provider used for 2FAtwoFactorRemember
is set based on whether the user chose to "remember" their 2FA response
Validating request with 2FA response
When the Identity API receives the second authentication request that includes the additional 2FA properties, it performs the authentication process again.
This time, the server is able to validate the 2FA response. To do this, it calls ValidateAsync
on
the relevant IUserTwoFactorTokenProvider
implementation for the twoFactorProvider
sent by the
client in the request.
If the token is valid, a successful response is
generated and returned to the client. If the user chose to
remember their 2FA entry, this response includes a token in the TwoFactorToken
property that can
be included on subsequent requests to bypass 2FA.