Create a public and private key for your domain: http://www.google.com/recaptcha
Then the below code manages everything you'd need not based on the Session attempts but Application attempts:
public class RecaptchaManager { #region Local variables private static volatile RecaptchaManager _instance; private static readonly object SyncRoot = new Object(); private readonly Byte _maxNumberOfValidFailedAttempts; private readonly Byte _durationInMinutes; private readonly int _cleanUpMaxSize; private readonly string _privateKey; private readonly string _publicKey; private readonly List_result = new List (); /// /// Be careful where and how the locks are used to avoid deadlocks or inter locks. /// private readonly Object _lockObject = new object(); #endregion #region Constructors and class initialization private RecaptchaManager() { if (!Byte.TryParse(SettingHelper.Instance["Recaptcha.ValidFailedAttempts.MaxNumber"], out _maxNumberOfValidFailedAttempts)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.ValidFailedAttempts.MaxNumber"); } if (!Byte.TryParse(SettingHelper.Instance["Recaptcha.ValidFailedAttempts.DurationInMinutes"], out _durationInMinutes)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.ValidFailedAttempts.DurationInMinutes"); } if (!int.TryParse(SettingHelper.Instance["Recaptcha.CleanUp.MaxSize"], out _cleanUpMaxSize)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.CleanUp.MaxSize"); } // private key this._privateKey = SettingHelper.Instance["Recaptcha.PrivateKey"]; if (string.IsNullOrWhiteSpace(this._privateKey)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.PrivateKey"); } this._publicKey = SettingHelper.Instance["Recaptcha.PublicKey"]; if (string.IsNullOrWhiteSpace(this._publicKey)) { throw new ApplicationException("Invalid or non-existent config key: Recaptcha.PublicKey"); } } #endregion #region Properties public static RecaptchaManager Instance { get { if (_instance == null) { lock (SyncRoot) { if (_instance == null) _instance = new RecaptchaManager(); } } return _instance; } } public string PublicKey { get { return this._publicKey; } } #endregion #region public Methods public void AddFailedLoginAttempt() { // we may want to customize these addFailedLoginOrRegistrationAttempt(); } public void AddFailedRegistrationAttempt() { // we may want to customize these addFailedLoginOrRegistrationAttempt(); } public bool ShouldRequireRecaptcha() { return getNumberOfFailedAttemptsDuringThePeriod() > this._maxNumberOfValidFailedAttempts; } public bool IsRecaptchaAvailableOnPage() { // if this field exists then the Recaptcha is available string challengeValue = Utils.GetStringForm("recaptcha_challenge_field", null); return challengeValue != null; } public bool IsInputValueVerified() { string challengeValue = Utils.GetStringForm("recaptcha_challenge_field", null); string responseValue = Utils.GetStringForm("recaptcha_response_field", null); bool result = false; try { var captchaValidtor = new RecaptchaValidator() { // put it in web.config PrivateKey = this._privateKey, RemoteIP = HttpContext.Current.Request.UserHostAddress, Challenge = challengeValue, Response = responseValue }; result = captchaValidtor.Validate().IsValid; } catch { } return result; } #endregion #region Private functions private void addFailedLoginOrRegistrationAttempt() { lock (this._lockObject) { if (this._result.Count > this._cleanUpMaxSize) { this.removeOldData(); } this._result.Add(DateTime.Now); } } ////// Removes the old data. /// private void removeOldData() { DateTime startDateTime = getStartDateTime(); this._result.RemoveAll(item => item < startDateTime); } private int getNumberOfFailedAttemptsDuringThePeriod() { DateTime startDateTime = getStartDateTime(); lock (this._lockObject) { return this._result.Count(failedAttemp => failedAttemp > startDateTime); } } private DateTime getStartDateTime() { return DateTime.Now.AddMinutes(-this._durationInMinutes); } #endregion }
No comments:
Post a Comment