Proof of concept website for two factor authentication (2 challenges ala "guess the password").
The site supports login via a simple 2-stage password challenge:
-
The first screen is the landing page which has just a simple password field and a submit ('login') button. It also contains a hidden input field right before the visible password field, containing the password in a numeric format. When the user submits the correct password he is redirected to the second screen.
-
The second screen has (again) a password input field and a submit ('login') button. It also has a specially crafted image containing the correct password embedded into the bottom of the image. When the user types in the correct password he's navigated to next and final view.
-
The third screen should include a title congratulating the user on logging in. It should include a download button. The download button should download this README.md file.
This is essentially a custom two-factor authentication mechanism. Like with all sane two-factor authentication mechanisms, provisions have been taken so that users who haven't succeeded in the first password challenge within the last X hours (where X is configurable and set to 24-hours by default) cannot proceed to step 2 via deep-link. If they attempt to do so they get redirected back to step 1.
-
Make sure:
a. You have SQL Server 2012+ running on your local machine (including services).
b. You have a DB called TwoFactorAuth and a db-user & owner of it called TwoFactorAuth with password '123456789'.
c. Doublecheck that your SqlServer allows logging both with Windows Authentication and via Sql Server Directly.
d. Last but not least edit appsettings.json and change 'Server=DROOD' to whatever your local server is running as
-
cd Code
-
dotnet restore
-
Open your .Net5.x-aware IDE of choice set the start-up type to 'IIS Express' and build/run the solution
-
Install Docker (with WSL2 support if you are running on Windows)
-
Follow steps 1 and 2 as described in the section 'IDE Build & Run'
-
Change the start-up type in your IDE to 'Docker' and simply run the solution (no need to tweak connection strings - everything is automagically configured!)
To build & run the docker image from the command line use (in a single line):
[LINUX DOCKER]
docker
build
-f "C:\VS\aspnet-core-dummy-two-factor-authentication\Code\Web\TwoFactorAuth.Web\Dockerfile"
--force-rm
-t twofactorauthweb:dev
--target base
--label "com.microsoft.created-by=visual-studio"
--label "com.microsoft.visual-studio.project-name=TwoFactorAuth.Web"
"C:\VS\aspnet-core-dummy-two-factor-authentication\Code"
[WINDOWS DOCKER]
docker
build
-f "C:\<path to>\aspnet-core-dummy-two-factor-authentication\Code\Web\TwoFactorAuth.Web\Dockerfile.windows"
--force-rm
-t twofactorauthweb:dev
--target base
--label "com.microsoft.created-by=visual-studio"
--label "com.microsoft.visual-studio.project-name=TwoFactorAuth.Web"
"C:\<path to>\aspnet-core-dummy-two-factor-authentication\Code"
The project is based off the dotnet template ASP.NET-Core-Template kind courtesy of Nikolay Kostov. It has been modified to employ Autofac and Mediatr.
This solution folder contains three subfolders:
- TwoFactorAuth.Web
- TwoFactorAuth.Web.ViewModels
- TwoFactorAuth.Web.Infrastructure
TwoFactorAuth.Web self explanatory.
The 2-stage authentication mechanism is implemented via the 'DummyTwoFactorAuthController'.
Note: In development mode the Web project advertises its API via Swagger under /swagger.
TwoFactorAuth.Web.ViewModels contains objects, which will be mapped from/to our entities and used in the front-end/back-end.
TwoFactorAuth.Web.Infrastructure contains functionality like Middlewares and Filters.
TwoFactorAuth.Common contains common things for the project solution. For example:
This solution folder contains three subfolders:
- TwoFactorAuth.Data.Common
- TwoFactorAuth.Data.Models
- TwoFactorAuth.Data
TwoFactorAuth.Data.Common.Models provides abstract generics classes and interfaces, which holds information about our entities. For example when the object is Created, Modified, Deleted or IsDeleted. It contains a property for the primary key as well.
TwoFactorAuth.Data.Common.Repositories provides two interfaces IDeletableEntityRepository and IRepository, which are part of the repository pattern.
TwoFactorAuth.Data.Models contains ApplicationUser and ApplicationRole classes, which inherits IdentityRole and IdentityUsers.
TwoFactorAuth.Data contains DbContext, Migrations and Configuraitons for the EF Core.There is Seeding and Repository functionality as well.
This solution folder contains four subfolders:
- TwoFactorAuth.Services
- TwoFactorAuth.Services.Data
- TwoFactorAuth.Services.Mapping
- TwoFactorAuth.Services.Messaging
TwoFactorAuth.Services.Data wil contains service layer logic.
TwoFactorAuth.Services.Mapping provides simplified functionlity for auto mapping. For example:
using Blog.Data.Models;
using Blog.Services.Mapping;
public class TagViewModel : IMapFrom<Tag>
{
public int Id { get; set; }
public string Name { get; set; }
}
Or if you have something specific:
using System;
using AutoMapper;
using Blog.Data.Models;
using Blog.Services.Mapping;
public class IndexPostViewModel : IMapFrom<Post>, IHaveCustomMappings
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string ImageUrl { get; set; }
public DateTime CreatedOn { get; set; }
public void CreateMappings(IProfileExpression configuration)
{
configuration.CreateMap<Post, IndexPostViewModel>()
.ForMember(
source => source.Author,
destination => destination.MapFrom(member => member.ApplicationUser.UserName));
}
}
TwoFactorAuth.Services.Messaging a ready to use integration with SendGrid.
This solution folder contains three subfolders:
- TwoFactorAuth.Services.Data.Tests
- TwoFactorAuth.Web.Tests
- Sandbox
TwoFactorAuth.Services.Data.Tests holds unit tests for our service layer with ready setted up xUnit.
TwoFactorAuth.Web.Tests setted up Selenuim tests.
Sandbox can be used to test your logic.