Skip to main content

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 POSTed 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 response
  • twoFactorProvider is set to the provider used for 2FA
  • twoFactorRemember 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.