Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116978

Add 2fa authenticator to user

I have been trying to work out how to enable 2f login with Google Authentication in my Identity server 4 application.

2fa works fine with both email and phone.

if i check

var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user);

it has two email and phone. I am assuming that this would be the two factor providers that have been set up for this user.

Now if i check _usermanager again there is a field called tokenproviders. Which appears to contain default, email, phone, and authenticator. I assume these are the ones that Asp .net identity is configured to deal with.

enter image description here

I have worked out how to create the secret needed to genreate the QR code for the authecator app. As well has how to build the QR code and to test the code

 var code = _userManager.GenerateNewAuthenticatorKey();      

 var qr = AuthencatorHelper.GetQrCodeGoogleUrl("bob", code, "My Company");

 var user = await _signInManager.TwoFactorAuthenticatorSignInAsync(codeFromAppToTestWith, true, false);
        if (user == null)
        {
            return View("Error");
        }

Now the problem. I have gone though every method I can find on the user trying to work out how to add another token provider to the user.

How do I assign a new token provider to the user and supply the secret code needed to create the authentication codes?? I am not even seeing any tables in the database setup to handle this information. email and phone number are there and there is a column for 2faenabled. But nothing about authenticator.

I am currently looking into creating a custom usermanager and adding a field onto the application user. I was really hoping someone had a better idea.

Upvotes: 6

Views: 4266

Answers (1)

Federico Dipuma
Federico Dipuma

Reputation: 18265

From what I can see, you are generating a new authenticator key each time the user needs to configure an authenticator app:

var code = _userManager.GenerateNewAuthenticatorKey(); 

You should be aware that using GenerateNewAuthenticatorCodeAsync will not persist the key, and thus will not be useful for 2FA.

Instead, you need to generate and persist the key in the underlying storage, if it not already created:

var key = await _userManager.GetAuthenticatorKeyAsync(user); // get the key
if (string.IsNullOrEmpty(key))
{ 
    // if no key exists, generate one and persist it
    await _userManager.ResetAuthenticatorKeyAsync(user);
    // get the key we just created
    key = await _userManager.GetAuthenticatorKeyAsync(user);
}

Which will generate the key if not already done and persist it in the database (or any storage configured for Identity).

Without persisting the key inside the storage, the AuthenticatorTokenProvider will never be able to generate tokens, and will not be available when calling GetValidTwoFactorProvidersAsync.

Upvotes: 3

Related Questions