After I enter the username and password, is it possible to show a screen for OTP where I can choose to receive the code by email or SMS?Are there any settings in the ABP Framework that can achieve this?
Version="9.0.4"
2 Answer(s)
-
0
- Solution
Yes. ABP supports showing an OTP step after a successful username/password login (Two-Factor Authentication). Users can use Email, SMS, or an Authenticator app. You can allow the user to choose Email or SMS on the OTP screen, or you can restrict to one provider.
Enable 2FA and providers:
- Email provider requires EmailConfirmed = true and a configured email sender (in Release).
- SMS provider requires PhoneNumberConfirmed = true and an ISmsSender implementation (e.g., Twilio SMS module).
- TOTP authenticator can be enabled by the user from the account/manage page.
How the built-in flow works:
- Call /connect/token with username/password (resource owner password flow). If 2FA is required, response includes error_description = RequiresTwoFactor with userId and twoFactorToken.
- Send the code:
- POST /api/account/send-two-factor-code with body: { token, userId, provider: "Email" | "SMS" }
- Get the delivered code (email/SMS).
- Retry /connect/token adding TwoFactorProvider and TwoFactorCode in the form body: grant_type=password client_id=... username=... password=... scope=... TwoFactorProvider=Email or SMS TwoFactorCode=123456 After that, the token is issued.
Let the user choose Email or SMS:
- Use the built-in “Send Security Code” page (Account/SendSecurityCode.cshtml) which shows the provider dropdown. In Blazor Server UI, you can override this page by copying it under YourProject.Blazor/Pages/Account/SendSecurityCode.cshtml and customize the UI to present Email/SMS choices you prefer.
- If you want to customize available providers, override AccountAppService.GetTwoFactorProvidersAsync and return only the providers you allow or in the order you want. Example:
public class MyAccountAppService : AccountAppService { public override async Task<ListResultDto<NameValue>> GetTwoFactorProvidersAsync(GetTwoFactorProvidersInput input) { var result = await base.GetTwoFactorProvidersAsync(input); // Keep only Email and SMS result.Items = result.Items.Where(p => p.Name == "Email" || p.Name == "SMS").ToList(); return result; } }Register your derived service in your module to replace the default IAccountAppService.
If you want to force a single provider (e.g., SMS only) and remove the dropdown:
- Override GetTwoFactorProvidersAsync to return only SMS.
- Override the SendSecurityCode UI (SendSecurityCode.cshtml) to remove the provider selection and post provider="SMS" automatically.
- In Blazor Server, place the overridden page under YourProject.Blazor/Pages/Account/SendSecurityCode.cshtml (and optional code-behind) so it overrides the module page.
Notes and prerequisites:
- Email provider: configure SMTP in appsettings for production; in DEBUG, codes are logged.
- SMS provider: install/configure Twilio SMS module or your own ISmsSender. In DEBUG, codes are logged; in production, ensure E.164 phone formatting to avoid vendor errors.
- If you always get RequiresTwoFactor on /connect/token even after verifying the code, ensure you include TwoFactorProvider and TwoFactorCode in the second /connect/token call, and preserve tenant context if multi-tenant.
- Sources
- https://github.com/abpframework/abp
- https://abp.io/support/questions/4444
- https://abp.io/support/questions/9956
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
-
0
