Skip to content

RFC 6238 Two-Factor Authentication service fails on .NET Framework 4.8 #54634

Description

@Choonster

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When calling Microsoft.AspNetCore.Identity.UserManager.VerifyTwoFactorTokenAsync in a .NET Framework 4.8 application, a NullReferenceException will be thrown due to Rfc6238AuthenticationService.ComputeTotp passing a null value to Rfc6238AuthenticationService.ApplyModifier for the modifierBytes argument.

Expected Behavior

UserManager.VerifyTwoFactorTokenAsync should return either true or false depending on whether the token was valid.

Steps To Reproduce

To reproduce:

  • Open the project in Visual Studio
  • Run the application
  • Click the "Test 2FA" button
  • Observe that the output below the button displays a NullReferenceException instead of an IdentityResult

Exceptions (if any)

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.AspNetCore.Identity.Rfc6238AuthenticationService.ApplyModifier(Span`1 input, Byte[] modifierBytes)
   at Microsoft.AspNetCore.Identity.Rfc6238AuthenticationService.ComputeTotp(HashAlgorithm hashAlgorithm, UInt64 timestepNumber, Byte[] modifierBytes)
   at Microsoft.AspNetCore.Identity.AuthenticatorTokenProvider`1.<ValidateAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.AspNetCore.Identity.UserManager`1.<VerifyTwoFactorTokenAsync>d__133.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at AspNetCoreIdentityRfc6238Error.Controllers.TwoFactorController.<Test2faAsync>d__2.MoveNext() in C:\Users\[USER]\source\repos\AspNetCoreIdentityRfc6238Error\AspNetCoreIdentityRfc6238Error\Controllers\TwoFactorController.cs:line 38
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()

.NET Version

.NET Framework 4.8

Anything else?

  • Microsoft.Extensions.Identity.Core version: 8.0.3
  • VS version: Microsoft Visual Studio Professional 2022 (64-bit) - Current - Version 17.9.2

This seems to have been introduced in #44557, which was released with .NET 8.0. Version 7.0.17 of the package doesn't have this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions