public IPAddress GetRemoteIpAddress()
        {
            IPAddress remoteIpAddress;

            IPAddress.TryParse(_owinContext.GetRemoteClientIpAddress(), out remoteIpAddress);
            return(remoteIpAddress);
        }
        public static async Task <IOpenIdConnectRequest> ToOpenIdConnectRequest(this IOwinContext owinContext)
        {
            var formAsNameValueCollection = await owinContext.ReadRequestFormAsync();

            IPAddress remoteIpAddress;

            IPAddress.TryParse(owinContext.GetRemoteClientIpAddress(), out remoteIpAddress);

            return(new OpenIdConnectRequest(remoteIpAddress, owinContext.ResourcePath(), owinContext.Request.Headers, formAsNameValueCollection));
        }
        public static bool IsExcluded(this RecaptchaValidationOptions recaptchaValidationOptions, IOwinContext owinContext, IOpenIdConnectRequest openIdConnectRequest)
        {
            var subnetExcluded = recaptchaValidationOptions.ExcludedSubnets.Any(excludedSubnet =>
            {
                var remoteClientIpAddress = owinContext.GetRemoteClientIpAddress();
                IPAddress ipAaddress;
                return(IPAddress.TryParse(remoteClientIpAddress, out ipAaddress) && excludedSubnet.Contains(ipAaddress));
            });

            if (subnetExcluded)
            {
                return(true);
            }

            if (openIdConnectRequest == null)
            {
                return(false);
            }

            var username = openIdConnectRequest.GetUsername();

            if (!string.IsNullOrEmpty(username) && recaptchaValidationOptions.ExcludedUsernameExpression != null &&
                recaptchaValidationOptions.ExcludedUsernameExpression.IsMatch(username))
            {
                return(true);
            }

            var tenant = openIdConnectRequest.GetTenant();

            if (!string.IsNullOrEmpty(tenant) && recaptchaValidationOptions.ExcludedTenantExpression != null &&
                recaptchaValidationOptions.ExcludedTenantExpression.IsMatch(tenant))
            {
                return(true);
            }

            var osVersion = openIdConnectRequest.GetOsVersion();

            if (!string.IsNullOrEmpty(osVersion) && recaptchaValidationOptions.ExcludedOsVersionExpression != null &&
                recaptchaValidationOptions.ExcludedOsVersionExpression.IsMatch(osVersion))
            {
                return(true);
            }

            return(false);
        }
        public override async Task Invoke(IOwinContext context)
        {
            var recaptchaValidationResource = context.ReadRequestBodyAsync <RecaptchaValidationResource>();
            var openIdConnectRequest        = recaptchaValidationResource == null ? null :
                                              new ValidationResourceBasedOpenIdConnectRequest(recaptchaValidationResource, context);
            var isExcludedFromRecaptcha = _options.IsExcluded(context, openIdConnectRequest);

            if (!_options.Matches(context) || isExcludedFromRecaptcha)
            {
                await Next.Invoke(context);

                return;
            }

            var       loginStatistics       = context.Get <ILoginStatistics>();
            var       remoteClientIpAddress = context.GetRemoteClientIpAddress();
            IPAddress ipAaddress;

            if (!IPAddress.TryParse(remoteClientIpAddress, out ipAaddress))
            {
                await Next.Invoke(context);

                return;
            }

            var challengeForAllLogins = await ShouldChallengeForAllLogins(context);

            if (!challengeForAllLogins &&
                await loginStatistics.GetNumberOfFailedLoginsForIpAddress(ipAaddress) < _options.NumberOfAllowedLoginFailuresPerIpAddress)
            {
                await Next.Invoke(context);

                return;
            }

            await ChallengeWithRequestForRecaptcha(context, openIdConnectRequest);
        }