ASP.NET Core Identity 2FA with Authenticator app in ASP.NEt Core Web API

122 views Asked by At

I am developing an API in ASP.NET Core 8 using ASP.NET Core identity which uses 2FA with Authenticator app for users who have enabled it.

The problem is this. I have checked on the 2FA with Authenticator app implementation in Razor pages, and it creates a cookie by the name Identity.TwoFactorUserId and has value CfDJ8MEoYd_uBmxNsdLp... when the user logins with user name and password who has enabled 2FA. And this cookie is used to identify the user and validate the 2FA code from the Authenticator app

enter image description here

In my case I am using JWT for my API. So once a user who has enabled 2FA with Authenticator app logins with username and password, he will be prompted to enter the code from the authenticator app. But with my API, there is no way to identify the user when validating the 2FA code. How can i generate a code like above in the cookie which is like Identity.TwoFactorUserId and has value CfDJ8MEoYd_uBmxNsdLp... in my API? or is there any other better way so that once the user enters the username and passowrd, then i can send him the Identity.TwoFactorUserId like code so that the front end will again pass the same code with the 2FA code to identify the user?

1

There are 1 answers

1
Jalpa Panchal On

For temporary token you could generate random string with the expiration time. by using this token you can maintain the state between login and 2FA verification.

sample code:

2FA Initiation:

public IActionResult Login(LoginModel model)
{
    // ... Login code

    if (IsTwoFactorRequired(user))
    {
        var twoFactorToken = GenerateTwoFactorToken(user.Id);
        // Save the token somewhere e.g database, with expiration time
        StoreTwoFactorToken(twoFactorToken);

        // Return this token to the client
        return Ok(new { twoFactorToken });
    }

    // ... Generate JWT if not using 2FA
}

Generate a token for the user, could be a GUID, or an encrypted value that contains the user ID:

private string GenerateTwoFactorToken(string userId)
{
    return Convert.ToBase64String(RandomNumberGenerator.GetBytes(64));
}

2FA Verification:

public IActionResult VerifyTwoFactor(string twoFactorToken, string twoFactorCode)
{
    if (ValidateTwoFactorToken(twoFactorToken))
    {
        // Get the user based on the Token
        var userId = GetUserIdFromToken(twoFactorToken);

        if (ValidateTwoFactorCode(userId, twoFactorCode))
        {
            // Generate JWT and return to the client
            var token = GenerateJwtToken(userId);
            return Ok(new { token });
        }
    }

    return Unauthorized();
}

Validate the format and, optionally, the existence of the token in the database or cache:

private bool ValidateTwoFactorToken(string twoFactorToken)
{
    // Token validation code
}