Site icon Tutexchange

How to Implement Captcha in ASP.NET CORE

Advertisements

How to Implement Captcha in ASP.NET CORE

In this article, we are going to learn to implement DNTCaptcha.Core Captcha in asp.net core in simple steps.

DNTCaptcha.Core is written by Vahid Nasiri.

Basically, we use Captcha on webpages to check webpages are accessed by humans not by bots. Without Captcha on webpages, there can be various attacks such as DOS (denial of service) attacks where Login page or registration page can be scripted and submit by using bots.

You can see Captcha are mostly used on Login, forgot password, Registration page right after logging into a web application we won’t use it mostly.

Table of Contents

Getting Started with Implementing Captcha in ASP.NET CORE

We are going to create a new application with Name WebCaptcha for demo as shown below.

Next, we are going to set Project Name WebCaptcha and location. In last part, we are going to choose .Net Core framework and ASP.NET Core Version 3.1 as the framework for application and few advance settings for such as configuring https and enabling docker we are not going to enable docker settings for this project.

Now finally click on create button to create a project.

Project structure

The project structure generated according to the configuration.

After creating project next, we are going to install DNTCaptcha.Core Package from NuGet Package.

Installing DNTCaptcha.Core Package from NuGet Package

After installing next, we are going to add TagHelper in _ViewImports.cshtml file.

Adding DNTCaptcha.Core TagHelper in _ViewImports.cshtml file

Adding @addTagHelper *, DNTCaptcha.Core directive to _ViewImports.cshtml file makes DNTCaptcha.Core Helpers available to the View.

_ViewImports.cshtml file is located in Views folder.

@using WebCaptcha
@using WebCaptcha.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, DNTCaptcha.Core

After adding DNTCaptcha.Core Tag Helpers next, we are going to add Model for Login in Models folder for showing captcha demo.

Adding Model

We are going to add a model in a Model folder with name LoginViewModel.

using System.ComponentModel.DataAnnotations;
namespace WebCaptcha.Models
{
    public class LoginViewModel
    {
        [Required(ErrorMessage = "Username Required")]
        public string Username { get; set; }

        [Required(ErrorMessage = "Password Required")]
        public string Password { get; set; }
    }
}

After adding LoginViewModel Next, let’s Add Controller and Action Method.

Adding Controller and Action Method

We are going to add a controller with name PortalController along with Login Action method to handle POST and GET method.

using Microsoft.AspNetCore.Mvc;
using WebCaptcha.Models;
namespace WebCaptcha.Controllers
{
    public class PortalController : Controller
    {
        [HttpGet]
        public IActionResult Login()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Login(LoginViewModel loginViewModel)
        {
            return View();
        }
    }
}

After adding Controller and Action Method next, we are going to register DNTCaptcha.Core Captcha Service in Startup class.

Registering DNTCaptcha.Core Captcha Service in Startup class ConfigureServices method

We have added AddDNTCaptcha Service here we have various options to configure we can use different Storage provider such as

  1. SessionStorageProvider
  2. MemoryCacheStorageProvider
  3. CookieStorageProvider
  4. DistributedCacheStorageProvider

Along with that, we can configure other options such as Expiration and Separators.

For this demo, we are going to use CookieStorageProvider.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddDNTCaptcha(options =>
        options.UseCookieStorageProvider()
            .ShowThousandsSeparators(false)
    );
}

After registering Service next we are going to add View and, on that View, we are going to use DNTCaptcha.Core Tag helper.

Adding Captcha on Login View

On Login View We are going to add 3 fields Username, password and Captcha.

Before adding Captcha on Login View let’s have a look at what different options, we can configure in it.

<dnt-captcha 
asp-captcha-generator-max="999999"
asp-captcha-generator-min="111111"
asp-captcha-generator-language="English"
asp-captcha-generator-display-mode="ShowDigits"
asp-use-relative-urls="true"
asp-placeholder="Enter Security code"
asp-validation-error-message="Please enter the security code."
asp-font-name="Tahoma"
asp-font-size="20"
asp-fore-color="#333333"
asp-back-color="#ccc"
asp-text-box-class="text-box form-control"
asp-text-box-template="<span class='input-group-prepend'><span class='form-group-text'></span></span>{0}"
asp-validation-message-class="text-danger"
asp-refresh-button-class="fas fa-redo btn-sm"
asp-use-noise="false" />

We can configure various options

Generator- language

We can configure Max and Min number if captcha generator along with that It supports 5 different languages.

  1. English
  2. Persian
  3. Norwegian
  4. Italian
  5. Turkish

Display Mode

There are 4 different Display Mode.

  1. NumberToWord
  2. ShowDigits
  3. SumOfTwoNumbers
  4. SumOfTwoNumbersToWords

Placeholder and ErrorMessage

We can Configure Custom Placeholder and Error Message.
Also, we can Customize various other options such as Font, Colour, Text box class, Error Message class.

Important Thing Required

  • Adding jquery.unobtrusive-ajax library

To make refresh button of Captcha to work we need to add jquery.unobtrusive-ajax library because of DNTCaptcha.Core use jquery.unobtrusive-ajax for refresh button you can download from below link and add to your project and reference it.

Link to Download:- https://github.com/aspnet/jquery-ajax-unobtrusive/releases

Code Snippet of Login View

@model LoginViewModel
@{
    Layout = null;
}

<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css" rel="stylesheet">

<div class="container">
    <br />
    <div class="col-md-4">
        <div class="card">
            <div class="card-body">

                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <form id="account" asp-controller="Portal" asp-antiforgery="true" asp-action="Login" method="post">

                    <span asp-validation-for="Username" class="text-danger"></span>
                    <div class="input-group mb-3">
                        <input asp-for="Username" class="form-control" placeholder="UserName" />
                    </div>
                    <span asp-validation-for="Password" class="text-danger"></span>
                    <div class="input-group mb-3">
                        <input type="password" asp-for="Password" autocomplete="new-password" class="form-control" placeholder="Password" />
                    </div>
                    <div class="input-group mb-3">

                        <dnt-captcha asp-captcha-generator-max="999999"
                                     asp-captcha-generator-min="111111"
                                     asp-captcha-generator-language="English"
                                     asp-captcha-generator-display-mode="ShowDigits"
                                     asp-use-relative-urls="true"
                                     asp-placeholder="Enter Captcha"
                                     asp-validation-error-message="Please enter the security code."
                                     asp-font-name="Tahoma"
                                     asp-font-size="20"
                                     asp-fore-color="#333333"
                                     asp-back-color="#ccc"
                                     asp-text-box-class="text-box form-control"
                                     asp-text-box-template="<span class='input-group-prepend'><span class='form-group-text'></span></span>{0}"
                                     asp-validation-message-class="text-danger"
                                     asp-refresh-button-class="fas fa-redo btn-sm"
                                     asp-use-noise="false" />



                    </div>
                    <div class="row">
                        <div class="col-8">

                        </div>
                        <div class="col-4">
                            <button type="submit" id="btnsubmit" class="btn btn-primary btn-block">Sign In</button>
                        </div>

                    </div>

                </form>

            </div>
        </div>

    </div>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="~/js/jquery.unobtrusive-ajax.js"></script>

Output

Validate Captcha on Post Request

To validate Captcha on Post DNTCaptcha has 2 method

ValidateDNTCaptcha attribute just we need to add it on Post Action method, and along with that, we have different option to configure such as ErrorMessage, CaptchaGeneratorLanguage and CaptchaGeneratorDisplayMode.

using DNTCaptcha.Core;
using DNTCaptcha.Core.Providers;
using Microsoft.AspNetCore.Mvc;
using WebCaptcha.Models;

namespace WebCaptcha.Controllers
{
    public class PortalController : Controller
    {
        [HttpGet]
        public IActionResult Login()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateDNTCaptcha(
            ErrorMessage = "Please Enter Valid Captcha", 
            CaptchaGeneratorLanguage = Language.English, 
            CaptchaGeneratorDisplayMode = DisplayMode.ShowDigits)]

        public IActionResult Login(LoginViewModel loginViewModel)
        {
            if (ModelState.IsValid)
            {

            }

            return View();
        }
    }
}

Using IDNTCaptchaValidatorService we can validate Captcha using method HasRequestValidCaptchaEntry method. Here we manually need to add error to ModelState.

using System;
using DNTCaptcha.Core;
using DNTCaptcha.Core.Providers;
using Microsoft.AspNetCore.Mvc;
using WebCaptcha.Models;

namespace WebCaptcha.Controllers
{
    public class PortalController : Controller
    {
        private readonly IDNTCaptchaValidatorService _validatorService;
        public PortalController(IDNTCaptchaValidatorService validatorService)
        {
            _validatorService = validatorService;
        }

        [HttpGet]
        public IActionResult Login()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Login(LoginViewModel loginViewModel)
        {
            if (ModelState.IsValid)
            {
                if (!_validatorService.HasRequestValidCaptchaEntry(Language.English, DisplayMode.ShowDigits))
                {
                    this.ModelState.AddModelError(DNTCaptchaTagHelper.CaptchaInputName, "Please Enter Valid Captcha.");
                    return View("Login");
                }
            }

            return View();
        }
    }
}

Try Different Modes

ShowDigits

SumOfTwoNumbers

Reference :- https://github.com/VahidN/DNTCaptcha.Core

Exit mobile version