I am using ASP Net identity with two factor authentication for user login.
I am generating two factor OTP like this
var token = await _userManager.GenerateTwoFactorTokenAsync(user, TokenOptions.DefaultEmailProvider);
I am sending this OTP to the user via email and then letting user login using this the OTP, this is the code I am using to validate the two factor authentication using token
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
var signIn = await _signInManager.TwoFactorSignInAsync(TokenOptions.DefaultEmailProvider, code, false, false);
if (signIn.Succeeded)
{
// further code
}
The default timeout of the OTP is 3 minutes and I know this is not OPT but TOTP so if I try to generate token within the 3 minutes time period I get the same OTP as the previous one.
Which is fine for me.
The problem is that even after 3 minutes are passed and so the new OTP is generated, when I try the last OTP (which is supposed to be expired and that is why the new OTP is generated) also works and allows user to sign in.
This behavior is totally wrong, once the new OTP is generated, the old ones should never work.
Could anybody guide me if I am doing something wrong in my code or is there a way to correct this behavior?
Difference Between TOTP and OTP
OTP and TOTP are two types of security mechanisms that usually perform the same function: verifying a user's identity for authentication.
One-Time Password (OTP) - OTP is a static password that becomes invalid after being used once. Unlike your registered password, it won’t be valid multiple times.
Time-Based One-Time Password (TOTP) - TOTP is a time-based OTP that requires the user to enter the OTP within a given time. This window of opportunity for entering the code in TOTP is usually 30 to 60 seconds. After that, the TOTP expires and you must be issued a new one.
OTP vs TOTP Key Difference - TOTPs and OTPs differ in how long their generated codes last, i.e., their validity. Most traditional OPTs are counter-based, i.e., each login session requires a new OTP to be generated.
TOTPs are time-based, i.e., the OTPs remain valid for a specified timeframe – usually 30 to 60 seconds, after which it expires and a new TOTP must be generated if you fail to enter the TOTP within that time.
https://instasafe.com/blog/whats-the-difference-between-otp-and-totp/
So an OTP will expire on first use, regardless of when that happens, whereas TOTP may expire in time. So if you want to have a timeout on your token, you will need to use TOTP instead of OTP. Are you sure you want to invalidate your token after 3 minutes if it is being sent via email? What if the person is not quick-enough to validate?
Nevertheless, if you want timeouts to happen if the token is not being used up in time, you will need to switch to using TOTP rather than OTP.
After subsequent discussion with the asker and subsequent research, we found out that the actual issue was the 9-minute window as per https://github.com/dotnet/aspnetcore/issues/27088
So, the exact issue seems to be detected and the asker is exploring possible solutions to it.