protected async override Task <bool> ValidateContextAsync(CustomTokenRequestValidationContext context, CustomValidatorRequestContext validatorContext) { var email = context.Result.ValidatedRequest.Subject?.GetDisplayName() ?? context.Result.ValidatedRequest.ClientClaims?.FirstOrDefault(claim => claim.Type == JwtClaimTypes.Email)?.Value; if (!string.IsNullOrWhiteSpace(email)) { validatorContext.User = await _userManager.FindByEmailAsync(email); } return(validatorContext.User != null); }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { if (!AuthEmailHeaderIsValid(context)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Auth-Email header invalid."); return; } var user = await _userManager.FindByEmailAsync(context.UserName.ToLowerInvariant()); var validatorContext = new CustomValidatorRequestContext { User = user, KnownDevice = await KnownDeviceAsync(user, context.Request) }; string bypassToken = null; if (!validatorContext.KnownDevice && _captchaValidationService.RequireCaptchaValidation(_currentContext, user)) { var captchaResponse = context.Request.Raw["captchaResponse"]?.ToString(); if (string.IsNullOrWhiteSpace(captchaResponse)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Captcha required.", new Dictionary <string, object> { { _captchaValidationService.SiteKeyResponseKeyName, _captchaValidationService.SiteKey }, }); return; } validatorContext.CaptchaResponse = await _captchaValidationService.ValidateCaptchaResponseAsync( captchaResponse, _currentContext.IpAddress, null); if (!validatorContext.CaptchaResponse.Success) { await BuildErrorResultAsync("Captcha is invalid. Please refresh and try again", false, context, null); return; } bypassToken = _captchaValidationService.GenerateCaptchaBypassToken(user); } await ValidateAsync(context, context.Request, validatorContext); if (context.Result.CustomResponse != null && bypassToken != null) { context.Result.CustomResponse["CaptchaBypassToken"] = bypassToken; } }
protected async override Task <bool> ValidateContextAsync(ResourceOwnerPasswordValidationContext context, CustomValidatorRequestContext validatorContext) { if (string.IsNullOrWhiteSpace(context.UserName) || validatorContext.User == null) { return(false); } if (!await _userService.CheckPasswordAsync(validatorContext.User, context.Password)) { return(false); } return(true); }
protected async Task ValidateAsync(T context, ValidatedTokenRequest request, CustomValidatorRequestContext validatorContext) { var isBot = (validatorContext.CaptchaResponse?.IsBot ?? false); if (isBot) { _logger.LogInformation(Constants.BypassFiltersEventId, "Login attempt for {0} detected as a captcha bot with score {1}.", request.UserName, validatorContext.CaptchaResponse.Score); } var twoFactorToken = request.Raw["TwoFactorToken"]?.ToString(); var twoFactorProvider = request.Raw["TwoFactorProvider"]?.ToString(); var twoFactorRemember = request.Raw["TwoFactorRemember"]?.ToString() == "1"; var twoFactorRequest = !string.IsNullOrWhiteSpace(twoFactorToken) && !string.IsNullOrWhiteSpace(twoFactorProvider); var valid = await ValidateContextAsync(context, validatorContext); var user = validatorContext.User; if (!valid) { await UpdateFailedAuthDetailsAsync(user, false, !validatorContext.KnownDevice); } if (!valid || isBot) { await BuildErrorResultAsync("Username or password is incorrect. Try again.", false, context, user); return; } var(isTwoFactorRequired, requires2FABecauseNewDevice, twoFactorOrganization) = await RequiresTwoFactorAsync(user, request); if (isTwoFactorRequired) { // Just defaulting it var twoFactorProviderType = TwoFactorProviderType.Authenticator; if (!twoFactorRequest || !Enum.TryParse(twoFactorProvider, out twoFactorProviderType)) { await BuildTwoFactorResultAsync(user, twoFactorOrganization, context, requires2FABecauseNewDevice); return; } BeforeVerifyTwoFactor(user, twoFactorProviderType, requires2FABecauseNewDevice); var verified = await VerifyTwoFactor(user, twoFactorOrganization, twoFactorProviderType, twoFactorToken); AfterVerifyTwoFactor(user, twoFactorProviderType, requires2FABecauseNewDevice); if ((!verified || isBot) && twoFactorProviderType != TwoFactorProviderType.Remember) { await UpdateFailedAuthDetailsAsync(user, true, !validatorContext.KnownDevice); await BuildErrorResultAsync("Two-step token is invalid. Try again.", true, context, user); return; } else if ((!verified || isBot) && twoFactorProviderType == TwoFactorProviderType.Remember) { // Delay for brute force. await Task.Delay(2000); await BuildTwoFactorResultAsync(user, twoFactorOrganization, context, requires2FABecauseNewDevice); return; } } else { twoFactorRequest = false; twoFactorRemember = false; twoFactorToken = null; } // Returns true if can finish validation process if (await IsValidAuthTypeAsync(user, request.GrantType)) { var device = await SaveDeviceAsync(user, request); if (device == null) { await BuildErrorResultAsync("No device information provided.", false, context, user); return; } await BuildSuccessResultAsync(user, context, device, twoFactorRequest&& twoFactorRemember); } else { SetSsoResult(context, new Dictionary <string, object> { { "ErrorModel", new ErrorResponseModel("SSO authentication is required.") } }); } }
protected abstract Task <bool> ValidateContextAsync(T context, CustomValidatorRequestContext validatorContext);