diff --git a/src/Core/Auth/Identity/TokenProviders/AuthenticatorTokenProvider.cs b/src/Core/Auth/Identity/TokenProviders/AuthenticatorTokenProvider.cs index 6348d6f27b2c..a68f37685785 100644 --- a/src/Core/Auth/Identity/TokenProviders/AuthenticatorTokenProvider.cs +++ b/src/Core/Auth/Identity/TokenProviders/AuthenticatorTokenProvider.cs @@ -54,6 +54,8 @@ public async Task 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) diff --git a/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs b/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs index e57ed1c85f8f..3a0e6770c369 100644 --- a/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs @@ -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); @@ -119,6 +123,8 @@ 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"]; @@ -126,6 +132,11 @@ protected async Task ValidateAsync(T context, ValidatedTokenRequest request, 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)) diff --git a/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs b/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs index d9a4fdb485cb..3f59db226422 100644 --- a/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs @@ -95,6 +95,8 @@ public async Task 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)