From 3725dbf908eb4e829b2afeb653ed45f266042382 Mon Sep 17 00:00:00 2001 From: Jared Goodwin Date: Sun, 23 Feb 2020 14:44:48 -0800 Subject: [PATCH] Add option to require 2FA. --- README.md | 1 + Server/Pages/Index.cshtml.cs | 12 +++++++++++- Server/Pages/TwoFactorRequired.cshtml | 15 +++++++++++++++ Server/Pages/TwoFactorRequired.cshtml.cs | 17 +++++++++++++++++ Server/Services/ApplicationConfig.cs | 1 + Server/appsettings.json | 3 ++- 6 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 Server/Pages/TwoFactorRequired.cshtml create mode 100644 Server/Pages/TwoFactorRequired.cshtml.cs diff --git a/README.md b/README.md index 5979c0a1..cdb09c4d 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ Note: To retain your settings between upgrades, copy your settings to appsetting * DataRetentionInDays: How long event logs and remote command logs will be kept. * RemoteControlSessionLimit: How many concurrent remote control sessions are allowed per organization. * RemoteControlRequiresAuthentication: Whether the remote control page requires authentication to establish a connection. +* Require2FA: Require users to set up 2FA before they can use the main app. * AllowApiLogin: Whether to allow logging in via the API (see below). * TrustedCorsOrigins: For cross-origin API requests via JavaScript. The websites listed in this array with be allowed to make requests to the API. This does not grant authentication, which is still required on most endpoints. * KnownProxies: If your Nginx server is on a different machine and is forwarding requests to the Remotely server, you will need to add the IP of the Nginx server to this array. diff --git a/Server/Pages/Index.cshtml.cs b/Server/Pages/Index.cshtml.cs index 281f3441..668557f4 100644 --- a/Server/Pages/Index.cshtml.cs +++ b/Server/Pages/Index.cshtml.cs @@ -13,16 +13,20 @@ namespace Remotely.Server.Pages { public class IndexModel : PageModel { - public IndexModel(DataService dataService, SignInManager signInManager) + public IndexModel(DataService dataService, + SignInManager signInManager, + ApplicationConfig appConfig) { DataService = dataService; SignInManager = signInManager; + AppConfig = appConfig; } public string DefaultPrompt { get; set; } public List DeviceGroups { get; set; } = new List(); private DataService DataService { get; } private SignInManager SignInManager { get; } + private ApplicationConfig AppConfig { get; } public async Task OnGet() { @@ -34,6 +38,12 @@ namespace Remotely.Server.Pages await SignInManager.SignOutAsync(); return RedirectToPage(); } + + if (AppConfig.RequireMFA && !user.TwoFactorEnabled) + { + return RedirectToPage("TwoFactorRequired"); + } + DefaultPrompt = DataService.GetDefaultPrompt(User.Identity.Name); var groups = DataService.GetDeviceGroupsForUserName(User.Identity.Name); if (groups?.Any() == true) diff --git a/Server/Pages/TwoFactorRequired.cshtml b/Server/Pages/TwoFactorRequired.cshtml new file mode 100644 index 00000000..d0f4075c --- /dev/null +++ b/Server/Pages/TwoFactorRequired.cshtml @@ -0,0 +1,15 @@ +@page +@model Remotely.Server.TwoFactorRequiredModel +@{ + ViewData["Title"] = "TwoFactorRequired"; +} + +

Two-Factor Authentication Required

+ +
+
+
+
Two-factor authentication is required. Click the button below to set up your authenticator app.
+ Enable 2FA +
+
diff --git a/Server/Pages/TwoFactorRequired.cshtml.cs b/Server/Pages/TwoFactorRequired.cshtml.cs new file mode 100644 index 00000000..a91a463f --- /dev/null +++ b/Server/Pages/TwoFactorRequired.cshtml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Remotely.Server +{ + public class TwoFactorRequiredModel : PageModel + { + public void OnGet() + { + + } + } +} \ No newline at end of file diff --git a/Server/Services/ApplicationConfig.cs b/Server/Services/ApplicationConfig.cs index 450a8e97..3b354e91 100644 --- a/Server/Services/ApplicationConfig.cs +++ b/Server/Services/ApplicationConfig.cs @@ -25,6 +25,7 @@ namespace Remotely.Server.Services public bool RedirectToHttps => bool.Parse(Config["ApplicationOptions:RedirectToHttps"]); public bool RemoteControlRequiresAuthentication => bool.Parse(Config["ApplicationOptions:RemoteControlRequiresAuthentication"]); public double RemoteControlSessionLimit => double.Parse(Config["ApplicationOptions:RemoteControlSessionLimit"]); + public bool Require2FA => bool.Parse(Config["ApplicationOptions:Require2FA"]); public string SmtpDisplayName => Config["ApplicationOptions:SmtpDisplayName"]; public string SmtpEmail => Config["ApplicationOptions:SmtpEmail"]; public bool SmtpEnableSsl => bool.Parse(Config["ApplicationOptions:SmtpEnableSsl"]); diff --git a/Server/appsettings.json b/Server/appsettings.json index e20f5129..3bd4ddd3 100644 --- a/Server/appsettings.json +++ b/Server/appsettings.json @@ -20,7 +20,8 @@ "RecordRemoteControlSessions": false, "RedirectToHttps": false, "RemoteControlSessionLimit": 1, - "RemoteControlRequiresAuthentication": true, + "RemoteControlRequiresAuthentication": true, + "Require2FA": false, "SmtpHost": "", "SmtpPort": 25, "SmtpUserName": "",