Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public async Task<bool> ValidateAsync(string purpose, string token, UserManager<

var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Authenticator);
var otp = new Totp(Base32Encoding.ToBytes((string)provider.MetaData["Key"]));

// TODO: the out var is a timestepMatched; consider logging it.
var valid = otp.VerifyTotp(token, out _, new VerificationWindow(1, 1));

if (valid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ protected async Task ValidateAsync(T context, ValidatedTokenRequest request,
return;
}

// TODO: ensure integration testing and then extract two factor logic into _twoFactorAuthenticationValidator.validate
// as step 1 so we can have confidence in changes for adding NDV soft lock
// Consider adding integration test for current brute force behavior

// 3. Check if 2FA is required.
(validatorContext.TwoFactorRequired, var twoFactorOrganization) =
await _twoFactorAuthenticationValidator.RequiresTwoFactorAsync(user, request);
Expand All @@ -119,13 +123,20 @@ protected async Task ValidateAsync(T context, ValidatedTokenRequest request,
// authentication is successful.
var returnRememberMeToken = false;

// TODO: for resource owner password validator flows, we will always know known device status here
// because we have to look it up in that validator and add it to the context.
if (validatorContext.TwoFactorRequired)
{
var twoFactorToken = request.Raw["TwoFactorToken"];
var twoFactorProvider = request.Raw["TwoFactorProvider"];
var validTwoFactorRequest = !string.IsNullOrWhiteSpace(twoFactorToken) &&
!string.IsNullOrWhiteSpace(twoFactorProvider);

// TODO: we must check cache for for account authenticator 2FA failure count and see if past threshold to
// be considered soft locked.

// TODO: how do we get new device verification response here?

// 3a. Response for 2FA required and not provided state.
if (!validTwoFactorRequest ||
!Enum.TryParse(twoFactorProvider, out TwoFactorProviderType twoFactorProviderType))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public async Task<bool> ValidateRequestDeviceAsync(ValidatedTokenRequest request
var validationResult = await HandleNewDeviceVerificationAsync(context.User, request);
if (validationResult != DeviceValidationResultType.Success)
{
// TODO: extract device validator return NDV required response as public method for injection
// and use in _twoFactorAuthenticationValidator?
(context.ValidationErrorResult, context.CustomResponse) =
BuildDeviceErrorResult(validationResult);
if (validationResult == DeviceValidationResultType.NewDeviceVerificationRequired)
Expand Down
Loading