This project explores the Captcha integration with Olive Framework.
The example is based on the training article provided on Captcha website. https://captcha.com/doc/aspnet/samples/csharp/asp.net-mvc-basic-captcha-sample.html.
This sample project uses Olive framework for proof of concept. Please follow the installation guidelines if you want to run the sample project and do not already have Msharp installed on your local machine. http://learn.msharp.co.uk/#/Install/README
Install Captcha nuget package on your Website project. The version that I am using is version 4.4.0.
Open Startup.cs and add the following lines.
public override void ConfigureServices(IServiceCollection services)
{
base.ConfigureServices(services);
services.AddDatabaseLogger();
services.AddScheduledTasks();
if (Environment.IsDevelopment())
services.AddDevCommands(x => x.AddTempDatabase<SqlServerManager, ReferenceData>());
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
});
}Override ConfigureRequestHandlers method with the following piece of code.
protected override void ConfigureRequestHandlers(IApplicationBuilder app)
{
app.UseSession();
UseStaticFiles(app);
app.UseRequestLocalization(RequestLocalizationOptions);
app.UseCaptcha(Configuration);
app.UseMvc();
}using BotDetect;
using BotDetect.Web.Mvc;
namespace Website
{
public static class CaptchaHelper
{
public static MvcCaptcha GetLoginCaptcha()
{
return new MvcCaptcha("LoginCaptcha")
{
UserInputID = "CaptchaCode",
ImageFormat = ImageFormat.Jpeg,
};
}
}
}Open _ViewImports.cshtml and add @addTagHelper "BotDetect.Web.Mvc.CaptchaTagHelper, BotDetect.Web.Mvc" at the end of the file.
Open Blank.Container.cshtml and add <link href="@BotDetect.Web.CaptchaUrls.Absolute.LayoutStyleSheetUrl" rel="stylesheet" type="text/css" /> within head section.
Add following piece of code to the Login.cshtml just below Password input.
@if (info.ShowCaptcha)
{
<div class="form-group row">
<label class="control-label">
</label>
<div class="group-control">
<div>
@{var loginCaptcha = Website.CaptchaHelper.GetLoginCaptcha();}
<captcha mvc-captcha="loginCaptcha" />
<div class="actions">
<input asp-for="CaptchaCode" class="form-control" placeholder="Captcha code" />
</div>
</div>
</div>
</div>
}Update your Login controller action to following.
[HttpPost("LoginForm/Login")]
public async Task<ActionResult> Login(vm.LoginForm info)
{
var mvcCaptcha = Website.CaptchaHelper.GetLoginCaptcha();
if (info.ShowCaptcha && !mvcCaptcha.Validate(info.CaptchaCode, Request.Param(mvcCaptcha.ValidatingInstanceKey)))
{
Notify("Invalid Captcha", "error");
info.ShowCaptcha = await LogonFailure.MustShowCaptcha(info.Email, Request.GetIPAddress());
return View(info);
}
var user = await Domain.User.FindByEmail(info.Email);
if ((user == null || !SecurePassword.Verify(info.Password, user.Password, user.Salt)))
{
Notify("Invalid username or password", "error");
info.ShowCaptcha = await LogonFailure.MustShowCaptcha(info.Email, Request.GetIPAddress());
return View(info);
}
await user.LogOn();
await LogonFailure.Remove(info.Email, Request.GetIPAddress());
if (Url.ReturnUrl().HasValue())
{
return Redirect(Url.ReturnUrl());
}
return Redirect(Url.Index("LoginDispatch"));
}Captcha plugin will randomize between various image styles. If you want to restrict the styles to limited set of styles then you can add the style configuration on appsettings.json
"BotDetect": {
"ImageStyle": "Bullets, BlackOverlap, Overlap"
}